num_bigfloat/
serde.rs

1//! Serialization and deserialization using different formats and data types.
2//!
3//! # Examples
4//!
5//! Suppose you have a struct that you want to serialize to json and you want the BigFloat values contained in the struct to be exported as formatted strings.
6//! The following is an example of how this can be achieved using `serde` field attributes and `num_bigfloat::serde::str` module:
7//!
8//! ``` rust
9//! use num_bigfloat::BigFloat;
10//! use serde::{Serialize, Deserialize};
11//!
12//! // A struct with a field of type BigFloat
13//! #[derive(Serialize, Deserialize)]
14//! struct SomeStruct {
15//!
16//!     #[serde(with = "num_bigfloat::serde::str")]
17//!     pub f: BigFloat,
18//! }
19//!
20//! // Value to be serialized
21//! let f = BigFloat::parse("-1.234567890123456789012345678901234567890e-12").unwrap();
22//! let val = SomeStruct {
23//!     f,
24//! };
25//!
26//! // Serialization
27//! let json = serde_json::to_string(&val).unwrap();
28//!
29//! // Result
30//! assert_eq!("{\"f\":\"-1.234567890123456789012345678901234567890e-12\"}", json);
31//! ```
32
33pub mod str {
34
35    //! Serialization to string and deserialization from string.
36
37    use crate::util::WritableBuf;
38    use crate::BigFloat;
39    use core::str::from_utf8_unchecked;
40    use serde::Deserializer;
41    use serde::Serializer;
42
43    use serde::de::{self, Visitor};
44
45    struct StrVisitor;
46
47    impl<'de> Visitor<'de> for StrVisitor {
48        type Value = BigFloat;
49
50        fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
51            formatter.write_str("a string representation of BigFloat")
52        }
53
54        fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
55        where
56            E: de::Error,
57        {
58            BigFloat::parse(value).ok_or_else(|| de::Error::custom("Failed to parse BigFloat"))
59        }
60    }
61
62    /// Serialize `f` to a string using given serializer.
63    pub fn serialize<S>(f: &BigFloat, serializer: S) -> Result<S::Ok, S::Error>
64    where
65        S: Serializer,
66    {
67        let mut buf = [0; 64];
68        let mut w = WritableBuf::new(&mut buf);
69
70        f.write_str(&mut w).unwrap();
71
72        let written_len = w.len();
73
74        let s = unsafe { from_utf8_unchecked(&buf[..written_len]) };
75
76        serializer.serialize_str(s)
77    }
78
79    /// Deserialize BigFloat from a string using given deserializer.
80    pub fn deserialize<'de, D>(deserializer: D) -> Result<BigFloat, D::Error>
81    where
82        D: Deserializer<'de>,
83    {
84        deserializer.deserialize_str(StrVisitor)
85    }
86}
87
88#[cfg(test)]
89mod tests {
90
91    use crate::BigFloat;
92    use serde::{Deserialize, Serialize};
93
94    #[derive(Serialize, Deserialize)]
95    struct Stub {
96        #[serde(with = "crate::serde::str")]
97        pub f: BigFloat,
98    }
99
100    #[test]
101    fn test_serde_str() {
102        // serialize
103        let f = BigFloat::parse("-1.234567890123456789012345678901234567890e-12").unwrap();
104        let stub = Stub { f };
105
106        let json = serde_json::to_string(&stub).unwrap();
107
108        assert_eq!(
109            "{\"f\":\"-1.234567890123456789012345678901234567890e-12\"}",
110            json
111        );
112
113        // deserialize
114        let f = BigFloat::parse("+9.123456789012345678901234567890123456789e+12").unwrap();
115        let json = "{
116            \"f\": \"9.123456789012345678901234567890123456789e+12\"
117        }";
118
119        let stub: Stub = serde_json::from_str(json).unwrap();
120
121        assert!(stub.f.cmp(&f) == Some(0));
122    }
123}