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