dashu_float/third_party/
serde.rs1use 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 serializer.collect_str(self)
41 } else {
42 let mut se = serializer.serialize_struct("FBig", 3)?;
44 se.serialize_field(KEY_SIGNIF, &self.repr.significand)?;
45 se.serialize_field(KEY_EXPONENT, &self.repr.exponent)?;
46 se.serialize_field(KEY_PREC, &self.context.precision)?;
47 se.end()
48 }
49 }
50}
51
52struct ReprVisitor<const BASE: Word>;
53
54impl<'de, const B: Word> Visitor<'de> for ReprVisitor<B> {
55 type Value = Repr<B>;
56
57 #[inline]
58 fn expecting(&self, formatter: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
59 formatter.write_str("float repr as a literal string or a struct (significand, exponent)")
60 }
61
62 #[inline]
63 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
64 #[allow(deprecated)] match Repr::<B>::from_str_native(v) {
66 Ok((repr, _)) => Ok(repr),
67 Err(e) => Err(de::Error::custom(e)),
68 }
69 }
70
71 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
72 let err_report = || {
73 de::Error::invalid_length(
74 2,
75 &"a float repr consists of two integer fields: (significand, exponent)",
76 )
77 };
78 let significand = seq.next_element()?.ok_or_else(err_report)?;
79 let exponent = seq.next_element()?.ok_or_else(err_report)?;
80
81 if seq.next_element::<de::IgnoredAny>()?.is_some() {
82 Err(err_report())?
83 } else {
84 Ok(Repr::new(significand, exponent))
85 }
86 }
87
88 fn visit_map<A: serde::de::MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
89 let mut signif: Option<IBig> = None;
90 let mut exp: Option<isize> = None;
91 while let Some(key) = map.next_key()? {
92 match key {
93 KEY_SIGNIF => {
94 if signif.is_some() {
95 return Err(de::Error::duplicate_field(KEY_SIGNIF));
96 }
97 signif = Some(map.next_value()?);
98 }
99 KEY_EXPONENT => {
100 if exp.is_some() {
101 return Err(de::Error::duplicate_field(KEY_EXPONENT));
102 }
103 exp = Some(map.next_value()?);
104 }
105 _ => return Err(de::Error::unknown_field(key, REPR_FIELDS)),
106 }
107 }
108
109 let significand = signif.ok_or_else(|| de::Error::missing_field(KEY_SIGNIF))?;
110 let exponent = exp.ok_or_else(|| de::Error::missing_field(KEY_EXPONENT))?;
111 Ok(Repr::new(significand, exponent))
112 }
113}
114
115impl<'de, const B: Word> Deserialize<'de> for Repr<B> {
116 #[inline]
117 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
118 if deserializer.is_human_readable() {
119 deserializer.deserialize_str(ReprVisitor)
120 } else {
121 deserializer.deserialize_struct("FBigRepr", REPR_FIELDS, ReprVisitor)
122 }
123 }
124}
125
126struct FBigVisitor<RoundingMode: Round, const BASE: Word>(PhantomData<RoundingMode>);
127
128impl<'de, R: Round, const B: Word> Visitor<'de> for FBigVisitor<R, B> {
129 type Value = FBig<R, B>;
130
131 #[inline]
132 fn expecting(&self, formatter: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
133 formatter.write_str(
134 "float number as a literal string or a struct (significand, exponent, precision)",
135 )
136 }
137
138 #[inline]
139 fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
140 #[allow(deprecated)] FBig::from_str_native(v).map_err(de::Error::custom)
142 }
143
144 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
145 let err_report = || {
146 de::Error::invalid_length(2,
147 &"a float number consists of three integer fields: (significand, exponent, precision)")
148 };
149 let significand = seq.next_element()?.ok_or_else(err_report)?;
150 let exponent = seq.next_element()?.ok_or_else(err_report)?;
151 let precision = seq.next_element()?.ok_or_else(err_report)?;
152
153 if seq.next_element::<de::IgnoredAny>()?.is_some() {
154 Err(err_report())?
155 } else {
156 Ok(FBig {
157 repr: Repr::new(significand, exponent),
158 context: Context::new(precision),
159 })
160 }
161 }
162
163 fn visit_map<A: serde::de::MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
164 let mut signif: Option<IBig> = None;
165 let mut exp: Option<isize> = None;
166 let mut prec: Option<usize> = None;
167 while let Some(key) = map.next_key()? {
168 match key {
169 KEY_SIGNIF => {
170 if signif.is_some() {
171 return Err(de::Error::duplicate_field(KEY_SIGNIF));
172 }
173 signif = Some(map.next_value()?);
174 }
175 KEY_EXPONENT => {
176 if exp.is_some() {
177 return Err(de::Error::duplicate_field(KEY_EXPONENT));
178 }
179 exp = Some(map.next_value()?);
180 }
181 KEY_PREC => {
182 if prec.is_some() {
183 return Err(de::Error::duplicate_field(KEY_PREC));
184 }
185 prec = Some(map.next_value()?);
186 }
187 _ => return Err(de::Error::unknown_field(key, REPR_FIELDS)),
188 }
189 }
190
191 let significand = signif.ok_or_else(|| de::Error::missing_field(KEY_SIGNIF))?;
192 let exponent = exp.ok_or_else(|| de::Error::missing_field(KEY_EXPONENT))?;
193 let precision = prec.ok_or_else(|| de::Error::missing_field(KEY_PREC))?;
194 Ok(FBig {
195 repr: Repr::new(significand, exponent),
196 context: Context::new(precision),
197 })
198 }
199}
200
201impl<'de, R: Round, const B: Word> Deserialize<'de> for FBig<R, B> {
202 #[inline]
203 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
204 if deserializer.is_human_readable() {
205 deserializer.deserialize_str(FBigVisitor(PhantomData))
206 } else {
207 deserializer.deserialize_struct("FBig", FBIG_FIELDS, FBigVisitor(PhantomData))
208 }
209 }
210}