1use serde::{
13 Deserialize, Deserializer, Serialize, Serializer,
14 de::{Error, SeqAccess, Visitor},
15 ser::{SerializeSeq, SerializeTuple},
16};
17
18use crate::{scalars::Scalar, vector::Vector};
19
20pub trait Exact: Sized {
23 fn write<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
24 fn read<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>;
25}
26
27pub fn serialize<T: Exact, S: Serializer>(value: &T, serializer: S) -> Result<S::Ok, S::Error> {
29 value.write(serializer)
30}
31
32pub fn deserialize<'de, T: Exact, D: Deserializer<'de>>(deserializer: D) -> Result<T, D::Error> {
34 T::read(deserializer)
35}
36
37pub struct Written<'a, T>(pub &'a T);
39
40impl<T: Exact> Serialize for Written<'_, T> {
41 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
42 self.0.write(serializer)
43 }
44}
45
46pub struct Read<T>(pub T);
48
49impl<'de, T: Exact> Deserialize<'de> for Read<T> {
50 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
51 T::read(deserializer).map(Read)
52 }
53}
54
55impl Exact for Scalar {
58 fn write<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
59 if self.lo.to_bits() == self.hi.to_bits() {
60 return serializer.serialize_f64(self.lo);
61 }
62 let mut pair = serializer.serialize_tuple(2)?;
63 pair.serialize_element(&self.lo)?;
64 pair.serialize_element(&self.hi)?;
65 pair.end()
66 }
67
68 fn read<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
69 struct Bounds;
70
71 impl<'de> Visitor<'de> for Bounds {
72 type Value = Scalar;
73
74 fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
75 write!(f, "a number, or its bounds [lo, hi]")
76 }
77
78 fn visit_f64<E: Error>(self, x: f64) -> Result<Scalar, E> {
79 Ok(Scalar { lo: x, hi: x })
80 }
81
82 #[expect(
83 clippy::cast_precision_loss,
84 reason = "a whole number written for an f64 was that f64"
85 )]
86 fn visit_i64<E: Error>(self, x: i64) -> Result<Scalar, E> {
87 self.visit_f64(x as f64)
88 }
89
90 #[expect(
91 clippy::cast_precision_loss,
92 reason = "a whole number written for an f64 was that f64"
93 )]
94 fn visit_u64<E: Error>(self, x: u64) -> Result<Scalar, E> {
95 self.visit_f64(x as f64)
96 }
97
98 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Scalar, A::Error> {
99 let lo: f64 = seq
100 .next_element()?
101 .ok_or_else(|| A::Error::invalid_length(0, &self))?;
102 let hi: f64 = seq
103 .next_element()?
104 .ok_or_else(|| A::Error::invalid_length(1, &self))?;
105 if seq.next_element::<serde::de::IgnoredAny>()?.is_some() {
106 return Err(A::Error::invalid_length(3, &self));
107 }
108 if lo.partial_cmp(&hi).is_none_or(std::cmp::Ordering::is_gt) {
110 return Err(A::Error::custom(format!("[{lo}, {hi}] is no interval")));
111 }
112 Ok(Scalar { lo, hi })
113 }
114 }
115
116 deserializer.deserialize_any(Bounds)
117 }
118}
119
120impl<const N: usize> Exact for Vector<N> {
122 fn write<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
123 let mut tuple = serializer.serialize_tuple(N)?;
124 for k in 0..N {
125 tuple.serialize_element(&Written(&self[k]))?;
126 }
127 tuple.end()
128 }
129
130 fn read<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
131 struct Components<const N: usize>;
132
133 impl<'de, const N: usize> Visitor<'de> for Components<N> {
134 type Value = Vector<N>;
135
136 fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
137 write!(f, "an array of {N} scalars")
138 }
139
140 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Vector<N>, A::Error> {
141 let mut out = Vector::zero();
142 for k in 0..N {
143 let Read(x) = seq
144 .next_element()?
145 .ok_or_else(|| A::Error::invalid_length(k, &self))?;
146 out[k] = x;
147 }
148 if seq.next_element::<serde::de::IgnoredAny>()?.is_some() {
149 return Err(A::Error::invalid_length(N + 1, &self));
150 }
151 Ok(out)
152 }
153 }
154
155 deserializer.deserialize_tuple(N, Components::<N>)
156 }
157}
158
159impl<T: Exact> Exact for Vec<T> {
161 fn write<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
162 let mut seq = serializer.serialize_seq(Some(self.len()))?;
163 for x in self {
164 seq.serialize_element(&Written(x))?;
165 }
166 seq.end()
167 }
168
169 fn read<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
170 let read = Vec::<Read<T>>::deserialize(deserializer)?;
171 Ok(read.into_iter().map(|Read(x)| x).collect())
172 }
173}
174
175#[cfg(test)]
176mod tests {
177 use super::*;
178
179 #[derive(Debug, PartialEq, Serialize, Deserialize)]
180 struct Kept {
181 #[serde(with = "crate::exact")]
182 points: Vec<Vector<2>>,
183 }
184
185 #[test]
188 fn scalars_read_back_as_written() {
189 let third = Scalar::from_f64(1.0).div(Scalar::from_f64(3.0)).unwrap();
190 let kept = Kept {
191 points: vec![
192 Vector::from_array([Scalar::from_f64(0.1), third]),
193 Vector::from_array([Scalar { lo: -0.0, hi: 0.0 }, Scalar::from_f64(-2.0)]),
194 ],
195 };
196 let text = serde_json::to_string(&kept).unwrap();
197 assert!(text.starts_with("{\"points\":[[0.1,["), "{text}");
198 let back: Kept = serde_json::from_str(&text).unwrap();
199 let bits = |k: &Kept| -> Vec<(u64, u64)> {
200 (k.points.iter())
201 .flat_map(|p| (0..2).map(move |i| (p[i].lo.to_bits(), p[i].hi.to_bits())))
202 .collect()
203 };
204 assert_eq!(bits(&back), bits(&kept));
205 }
206
207 #[test]
208 fn bounds_out_of_order_are_refused() {
209 assert!(serde_json::from_str::<Kept>("{\"points\":[[[2.0,1.0],0]]}").is_err());
210 }
211}