# serde-this-or-that [github](https://github.com/rnag/serde-this-or-that) [crates.io](https://crates.io/crates/serde-this-or-that) [docs.rs](https://docs.rs/serde-this-or-that) [build status](https://github.com/rnag/serde-this-or-that/actions?query=branch%3Amain) Custom deserialization for fields that can be specified as multiple types. --- This crate works with Cargo with a `Cargo.toml` like: ```toml [dependencies] serde-this-or-that = "0.4" serde = { version = "1", features = ["derive"] } serde_json = "1" ``` ## Getting started Add some usage to your application. Here's an example of using `serde-this-or-that` in code: ```rust use serde::Deserialize; use serde_json::from_str; use serde_this_or_that::{as_bool, as_f64, as_u64}; #[derive(Deserialize, Debug)] #[serde(rename_all = "camelCase")] struct MyStruct { #[serde(deserialize_with = "as_bool")] is_active: bool, #[serde(deserialize_with = "as_u64")] num_attempts: u64, #[serde(deserialize_with = "as_f64")] grade: f64, } fn main() -> Result<(), Box> { let string = r#" { "isActive": "True", "numAttempts": "", "grade": "81" } "#; let s: MyStruct = from_str(string)?; println!("{s:#?}"); assert!(s.is_active); assert_eq!(s.num_attempts, 0); assert_eq!(s.grade, 81.0); Ok(()) } ``` ## Exported Functions - [`as_bool`](https://docs.rs/serde-this-or-that/latest/serde_this_or_that/fn.as_bool.html) - [`as_f64`](https://docs.rs/serde-this-or-that/latest/serde_this_or_that/fn.as_f64.html) - [`as_i64`](https://docs.rs/serde-this-or-that/latest/serde_this_or_that/fn.as_i64.html) - [`as_string`](https://docs.rs/serde-this-or-that/latest/serde_this_or_that/fn.as_string.html) - [`as_u64`](https://docs.rs/serde-this-or-that/latest/serde_this_or_that/fn.as_u64.html) ## Examples You can check out sample usage of this crate in the [examples/](https://github.com/rnag/serde-this-or-that/tree/main/examples) folder in the project repo on GitHub. ## Performance The benchmarks suggest that implementing a custom [`Visitor`] as `serde-this-or-that` does, performs on average **about 15x better** than an approach with an [untagged enum]. A separate benchmark compares performance against the [serde_with] crate: it indicates both crates perform about the same, assuming only [`DisplayFromStr`] is used. But when [`PickFirst`] is involved, `serde-this-or-that` appears to perform **about 12x better** in an average case. The benchmarks live in the [benches/](https://github.com/rnag/serde-this-or-that/tree/main/benches) folder, and can be run with `cargo bench`. [`Visitor`]: https://docs.serde.rs/serde/de/trait.Visitor.html [untagged enum]: https://stackoverflow.com/a/66961340/10237506 [serde_with]: https://docs.rs/serde_with [`DisplayFromStr`]: https://docs.rs/serde_with/latest/serde_with/struct.DisplayFromStr.html [`PickFirst`]: https://docs.rs/serde_with/latest/serde_with/struct.PickFirst.html ## Contributing Contributions are welcome! Open a pull request to fix a bug, or [open an issue][] to discuss a new feature or change. Check out the [Contributing][] section in the docs for more info. [Contributing]: CONTRIBUTING.md [open an issue]: https://github.com/rnag/serde-this-or-that/issues ## License This project is proudly licensed under the MIT license ([LICENSE](LICENSE) or http://opensource.org/licenses/MIT). `serde-this-or-that` can be distributed according to the MIT license. Contributions will be accepted under the same license. ## Authors * [Ritvik Nag](https://github.com/rnag)