Skip to main content

fastnum/decimal/udec/extras/serde/
utils.rs

1//! # Unsigned decimal number serialization and deserialization utils for serde
2
3#[cfg(feature = "serde-arbitrary-precision")]
4mod details;
5
6#[cfg(feature = "serde-arbitrary-precision")]
7type UD<const N: usize> = crate::decimal::UnsignedDecimal<N>;
8
9/// Serialize/deserialize [crate::decimal::UnsignedDecimal] as arbitrary
10/// precision numbers in JSON using the `arbitrary_precision` feature within
11/// `serde_json`.
12///
13/// ```
14/// # use serde::Deserialize;
15/// # use fastnum::*;
16///
17/// #[derive(Deserialize)]
18/// pub struct Arbitrary {
19///     #[serde(with = "decimal::serde::udec::arbitrary_precision")]
20///     value: UD128,
21/// }
22///
23/// let data: Arbitrary = serde_json::from_str(r#"{"value": 1.09861228866810969139524523692252570465}"#).unwrap();
24/// assert_eq!(udec128!(1.09861228866810969139524523692252570465), data.value);
25/// ```
26#[cfg(feature = "serde-arbitrary-precision")]
27pub mod arbitrary_precision {
28    use super::*;
29
30    use serde::{de, Serialize};
31    use std::str::FromStr;
32
33    /// Deserializer for `[`#[serde(with = "...")]`](<https://serde.rs/field-attrs.html#with>).
34    pub fn deserialize<'de, D, const N: usize>(deserializer: D) -> Result<UD<N>, D::Error>
35    where
36        D: de::Deserializer<'de>,
37    {
38        deserializer.deserialize_any(details::Visitor)
39    }
40
41    /// Serializer for [`#[serde(with = "...")]`](<https://serde.rs/field-attrs.html#with>).
42    pub fn serialize<S, const N: usize>(value: &UD<N>, serializer: S) -> Result<S::Ok, S::Error>
43    where
44        S: serde::Serializer,
45    {
46        serde_json::Number::from_str(&value.to_string())
47            .map_err(serde::ser::Error::custom)?
48            .serialize(serializer)
49    }
50}
51
52/// Serialize/deserialize optional [crate::decimal::UnsignedDecimal] as
53/// arbitrary precision numbers in JSON using the `arbitrary_precision` feature
54/// within `serde_json`.
55///
56/// ```
57/// # use serde::Deserialize;
58/// # use fastnum::*;
59///
60/// #[derive(Deserialize)]
61/// pub struct Arbitrary {
62///     #[serde(with = "decimal::serde::udec::arbitrary_precision_option")]
63///     value: Option<UD128>,
64/// }
65///
66/// let data: Arbitrary = serde_json::from_str(r#"{"value": 1.09861228866810969139524523692252570465}"#).unwrap();
67/// assert_eq!(Some(udec128!(1.09861228866810969139524523692252570465)), data.value);
68///
69/// let data: Arbitrary = serde_json::from_str(r#"{"value": null}"#).unwrap();
70/// assert_eq!(None, data.value);
71/// ```
72#[cfg(feature = "serde-arbitrary-precision")]
73pub mod arbitrary_precision_option {
74    use super::*;
75
76    use serde::{de, Serialize};
77
78    /// Deserializer for [`#[serde(with = "...")]`](<https://serde.rs/field-attrs.html#with>).
79    pub fn deserialize<'de, D, const N: usize>(deserializer: D) -> Result<Option<UD<N>>, D::Error>
80    where
81        D: de::Deserializer<'de>,
82    {
83        deserializer.deserialize_option(details::OptionVisitor)
84    }
85
86    /// Serializer for [`#[serde(with = "...")]`](<https://serde.rs/field-attrs.html#with>).
87    pub fn serialize<S, const N: usize>(
88        value: &Option<UD<N>>,
89        serializer: S,
90    ) -> Result<S::Ok, S::Error>
91    where
92        S: serde::Serializer,
93    {
94        match value {
95            Some(decimal) => {
96                serde_json::Number::from_string_unchecked(decimal.to_string()).serialize(serializer)
97            }
98            None => serializer.serialize_none(),
99        }
100    }
101}