dashu_float/third_party/
serde.rs1extern 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 serializer.collect_str(self)
26 } else {
27 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 serializer.collect_str(self)
43 } else {
44 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)] 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)] 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}