Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customisable serialisation per field using serde's with attribute #459

Merged
merged 6 commits into from Jan 8, 2022
Merged

Customisable serialisation per field using serde's with attribute #459

merged 6 commits into from Jan 8, 2022

Conversation

ghost
Copy link

@ghost ghost commented Jan 7, 2022

Use case

Multiple services may use different methods for serialising numbers into JSON. Using the "features" feature, it's difficult to get the result you want, as adding the ability to serialise to arbitrary precision numbers may remove the ability to serialise to str numbers. The features are also not intuitive to set to achieve what you want. Multiple dependencies can also flight with eachother for which format should be the default.

Using Serde's with attribute allows developers to avoid these issues by setting the serialisation type per field, as well as keeping the features for backwards compatibility (and for setting a default if they wish).

Example (arbitrary) usage

Cargo.toml

[package]
name = "aaa"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rust_decimal_macros = "1"
serde_json = "1"

[dependencies.rust_decimal]
features = ["serde-with-arbitrary-precision", "serde-with-float", "serde-with-str"]
git = "https://github.com/ShigotoMitame/rust-decimal"
branch = "serde-with"

[dependencies.serde]
version = "1"
features = ["derive"]

src/main.rs

use rust_decimal_macros::dec;
use rust_decimal::Decimal;
use serde::{Serialize, Deserialize};

fn main() {
    #[derive(Serialize, Deserialize)]
    struct ExampleUsage {
        #[serde(with = "rust_decimal::serde::arbitrary_precision")]
        pub ap_value: Decimal,
        #[serde(with = "rust_decimal::serde::float")]
        pub float_value: Decimal,
        #[serde(with = "rust_decimal::serde::str")]
        pub str_value: Decimal,
    }

    let example_value = ExampleUsage {
        ap_value: dec!(123.400),
        float_value: dec!(567.800),
        str_value: dec!(819.200),
    };
    let example_result = serde_json::to_string(&example_value).unwrap();
    assert_eq!(&example_result, r#"{"ap_value":123.400,"float_value":567.8,"str_value":"819.200"}"#);
}

@paupino
Copy link
Owner

paupino commented Jan 8, 2022

This looks great and certainly makes sense to leverage. Do you mind running makers format on the code? It's a bit of a nit however it helps maintain a consistent style across the project.

@ghost
Copy link
Author

ghost commented Jan 8, 2022

Do you mind running makers format on the code? It's a bit of a nit however it helps maintain a consistent style across the project.

No problem -- slightly too used to having pre-commit stuff enabled. Do you want the branch rebased and the commits individually re-formatted? I've left it as a single fixing commit for now, but I don't mind either way.

I also updated the readme to document the new features.

@paupino
Copy link
Owner

paupino commented Jan 8, 2022

Cool, thank you! No need to rebase - I'll squash the commits anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant