dashu_float/third_party/
serde.rs

1//! Implement serde traits.
2
3extern crate alloc;
4
5use core::marker::PhantomData;
6
7use crate::{fbig::FBig, repr::Repr, round::Round, Context};
8use dashu_int::{IBig, Word};
9use serde::{
10    de::{self, Deserialize, Deserializer, SeqAccess, Visitor},
11    ser::{Serialize, SerializeStruct, Serializer},
12};
13
14const KEY_SIGNIF: &str = "significand";
15const KEY_EXPONENT: &str = "exponent";
16const KEY_PREC: &str = "precision";
17const REPR_FIELDS: &[&str] = &[KEY_SIGNIF, KEY_EXPONENT];
18const FBIG_FIELDS: &[&str] = &[KEY_SIGNIF, KEY_EXPONENT, KEY_PREC];
19
20impl<const B: Word> Serialize for Repr<B> {
21    #[inline]
22    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
23        if serializer.is_human_readable() {
24            // serialize to formatted string if the serializer is human readable
25            serializer.collect_str(self)
26        } else {
27            // otherwise serialize as a (significand, exponent) struct
28            let mut se = serializer.serialize_struct("FBigRepr", 2)?;
29            se.serialize_field(KEY_SIGNIF, &self.significand)?;
30            se.serialize_field(KEY_EXPONENT, &self.exponent)?;
31            se.end()
32        }
33    }
34}
35
36impl<R: Round, const B: Word> Serialize for FBig<R, B> {
37    #[inline]
38    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
39        if serializer.is_human_readable() {
40            // serialize to formatted string if the serializer is human readable
41            // TODO(next): pad the output with leading zeros to make the result contains the correct precision
42            serializer.collect_str(self)
43        } else {
44            // otherwise serialize as a (significand, exponent, precision) struct
45            let mut se = serializer.serialize_struct("FBig", 3)?;
46            se.serialize_field(KEY_SIGNIF, &self.repr.significand)?;
47            se.serialize_field(KEY_EXPONENT, &self.repr.exponent)?;
48            se.serialize_field(KEY_PREC, &self.context.precision)?;
49            se.end()
50        }
51    }
52}
53
54struct ReprVisitor<const BASE: Word>;
55
56impl<'de, const B: Word> Visitor<'de> for ReprVisitor<B> {
57    type Value = Repr<B>;
58
59    #[inline]
60    fn expecting(&self, formatter: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
61        formatter.write_str("float repr as a literal string or a struct (significand, exponent)")
62    }
63
64    #[inline]
65    fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
66        #[allow(deprecated)] // TODO(v0.5): remove after from_str_native is made private.
67        match Repr::<B>::from_str_native(v) {
68            Ok((repr, _)) => Ok(repr),
69            Err(e) => Err(de::Error::custom(e)),
70        }
71    }
72
73    fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
74        let err_report = || {
75            de::Error::invalid_length(
76                2,
77                &"a float repr consists of two integer fields: (significand, exponent)",
78            )
79        };
80        let significand = seq.next_element()?.ok_or_else(err_report)?;
81        let exponent = seq.next_element()?.ok_or_else(err_report)?;
82
83        if seq.next_element::<de::IgnoredAny>()?.is_some() {
84            Err(err_report())?
85        } else {
86            Ok(Repr::new(significand, exponent))
87        }
88    }
89
90    fn visit_map<A: serde::de::MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
91        let mut signif: Option<IBig> = None;
92        let mut exp: Option<isize> = None;
93        while let Some(key) = map.next_key()? {
94            match key {
95                KEY_SIGNIF => {
96                    if signif.is_some() {
97                        return Err(de::Error::duplicate_field(KEY_SIGNIF));
98                    }
99                    signif = Some(map.next_value()?);
100                }
101                KEY_EXPONENT => {
102                    if exp.is_some() {
103                        return Err(de::Error::duplicate_field(KEY_EXPONENT));
104                    }
105                    exp = Some(map.next_value()?);
106                }
107                _ => return Err(de::Error::unknown_field(key, REPR_FIELDS)),
108            }
109        }
110
111        let significand = signif.ok_or_else(|| de::Error::missing_field(KEY_SIGNIF))?;
112        let exponent = exp.ok_or_else(|| de::Error::missing_field(KEY_EXPONENT))?;
113        Ok(Repr::new(significand, exponent))
114    }
115}
116
117impl<'de, const B: Word> Deserialize<'de> for Repr<B> {
118    #[inline]
119    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
120        if deserializer.is_human_readable() {
121            deserializer.deserialize_str(ReprVisitor)
122        } else {
123            deserializer.deserialize_struct("FBigRepr", REPR_FIELDS, ReprVisitor)
124        }
125    }
126}
127
128struct FBigVisitor<RoundingMode: Round, const BASE: Word>(PhantomData<RoundingMode>);
129
130impl<'de, R: Round, const B: Word> Visitor<'de> for FBigVisitor<R, B> {
131    type Value = FBig<R, B>;
132
133    #[inline]
134    fn expecting(&self, formatter: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
135        formatter.write_str(
136            "float number as a literal string or a struct (significand, exponent, precision)",
137        )
138    }
139
140    #[inline]
141    fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
142        #[allow(deprecated)] // TODO(v0.5): remove after from_str_native is made private.
143        FBig::from_str_native(v).map_err(de::Error::custom)
144    }
145
146    fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
147        let err_report = || {
148            de::Error::invalid_length(2,
149            &"a float number consists of three integer fields: (significand, exponent, precision)")
150        };
151        let significand = seq.next_element()?.ok_or_else(err_report)?;
152        let exponent = seq.next_element()?.ok_or_else(err_report)?;
153        let precision = seq.next_element()?.ok_or_else(err_report)?;
154
155        if seq.next_element::<de::IgnoredAny>()?.is_some() {
156            Err(err_report())?
157        } else {
158            Ok(FBig {
159                repr: Repr::new(significand, exponent),
160                context: Context::new(precision),
161            })
162        }
163    }
164
165    fn visit_map<A: serde::de::MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
166        let mut signif: Option<IBig> = None;
167        let mut exp: Option<isize> = None;
168        let mut prec: Option<usize> = None;
169        while let Some(key) = map.next_key()? {
170            match key {
171                KEY_SIGNIF => {
172                    if signif.is_some() {
173                        return Err(de::Error::duplicate_field(KEY_SIGNIF));
174                    }
175                    signif = Some(map.next_value()?);
176                }
177                KEY_EXPONENT => {
178                    if exp.is_some() {
179                        return Err(de::Error::duplicate_field(KEY_EXPONENT));
180                    }
181                    exp = Some(map.next_value()?);
182                }
183                KEY_PREC => {
184                    if prec.is_some() {
185                        return Err(de::Error::duplicate_field(KEY_PREC));
186                    }
187                    prec = Some(map.next_value()?);
188                }
189                _ => return Err(de::Error::unknown_field(key, REPR_FIELDS)),
190            }
191        }
192
193        let significand = signif.ok_or_else(|| de::Error::missing_field(KEY_SIGNIF))?;
194        let exponent = exp.ok_or_else(|| de::Error::missing_field(KEY_EXPONENT))?;
195        let precision = prec.ok_or_else(|| de::Error::missing_field(KEY_PREC))?;
196        Ok(FBig {
197            repr: Repr::new(significand, exponent),
198            context: Context::new(precision),
199        })
200    }
201}
202
203impl<'de, R: Round, const B: Word> Deserialize<'de> for FBig<R, B> {
204    #[inline]
205    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
206        if deserializer.is_human_readable() {
207            deserializer.deserialize_str(FBigVisitor(PhantomData))
208        } else {
209            deserializer.deserialize_struct("FBig", FBIG_FIELDS, FBigVisitor(PhantomData))
210        }
211    }
212}