astro_float_num/for_3rd/
de.rs

1//! Deserialization of BigFloat.
2
3use core::fmt::Formatter;
4use core::str::FromStr;
5
6use crate::num::BigFloatNumber;
7use crate::BigFloat;
8use serde::de::Error;
9use serde::de::Visitor;
10use serde::{Deserialize, Deserializer};
11
12pub struct BigFloatVisitor {}
13
14impl<'de> Deserialize<'de> for BigFloat {
15    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
16        deserializer.deserialize_any(BigFloatVisitor {})
17    }
18}
19
20impl<'de> Visitor<'de> for BigFloatVisitor {
21    type Value = BigFloat;
22
23    fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
24        write!(formatter, "except `String`, `Number`, `Bytes`")
25    }
26
27    fn visit_u64<E: Error>(self, v: u64) -> Result<Self::Value, E> {
28        match BigFloatNumber::from_usize(v as usize) {
29            Ok(o) => Ok(o.into()),
30            Err(e) => Err(Error::custom(format!("{e:?}"))),
31        }
32    }
33
34    fn visit_f32<E: Error>(self, v: f32) -> Result<Self::Value, E> {
35        match BigFloatNumber::from_f64(64, v as f64) {
36            Ok(o) => Ok(o.into()),
37            Err(e) => Err(Error::custom(format!("{e:?}"))),
38        }
39    }
40
41    fn visit_f64<E: Error>(self, v: f64) -> Result<Self::Value, E> {
42        match BigFloatNumber::from_f64(64, v) {
43            Ok(o) => Ok(o.into()),
44            Err(e) => Err(Error::custom(format!("{e:?}"))),
45        }
46    }
47
48    fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
49        match BigFloat::from_str(v) {
50            Ok(o) => Ok(o),
51            Err(e) => Err(Error::custom(format!("{e:?}"))),
52        }
53    }
54
55    fn visit_string<E: Error>(self, v: String) -> Result<Self::Value, E> {
56        self.visit_str(&v)
57    }
58
59    // lossless conversion
60    // (&[Word], usize, Sign, Exponent)
61    // (s * len, s    , 1   , 1       )
62    // fn visit_bytes<E: Error>(self, _: &[u8]) -> Result<Self::Value, E> {
63    //     todo!()
64    // }
65}
66
67#[cfg(test)]
68mod tests {
69
70    use core::str::FromStr;
71
72    use serde_json::from_str;
73
74    use crate::BigFloat;
75
76    #[cfg(not(feature = "std"))]
77    use alloc::format;
78
79    #[test]
80    fn from_json() {
81        let x = BigFloat::new(1);
82        assert_eq!(x, from_str::<BigFloat>("-0").unwrap());
83        assert_eq!(x, from_str::<BigFloat>("0.0").unwrap());
84
85        let x = BigFloat::from_f64(0.3, 64);
86        assert_eq!(x, from_str::<BigFloat>("0.3").unwrap());
87
88        let x = BigFloat::from_str("0.3").unwrap();
89        assert_eq!(x, from_str::<BigFloat>("\"0.3\"").unwrap());
90    }
91}