Skip to main content

mmdb_writer/
ser.rs

1//! A `serde::Serializer` that projects any `Serialize` value into a [`Value`], gated on the
2//! `serde` feature.
3//!
4//! MMDB has no null type, so the serializer's `Ok` type is `Option<Value>`: `None` means
5//! *"the parent map/struct should drop this entry"*. Only `Option::None`, `()`, and unit
6//! structs produce `None`.
7
8use std::collections::BTreeMap;
9
10use serde::Serialize;
11use serde::ser::{
12    self, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
13    SerializeTupleStruct, SerializeTupleVariant,
14};
15
16use crate::error::Error;
17use crate::value::Value;
18
19impl ser::Error for Error {
20    fn custom<T: std::fmt::Display>(msg: T) -> Self {
21        Error::Serialize(msg.to_string())
22    }
23}
24
25/// Serialize any `Serialize` value into an MMDB [`Value`].
26pub(crate) fn to_value<T: Serialize + ?Sized>(value: &T) -> Result<Value, Error> {
27    value
28        .serialize(ValueSerializer)?
29        .ok_or(Error::UnsupportedValue("top-level null / Option::None"))
30}
31
32struct ValueSerializer;
33
34/// `None` = "drop this entry" (used by map/struct parents).
35type Out = Option<Value>;
36
37impl ser::Serializer for ValueSerializer {
38    type Ok = Out;
39    type Error = Error;
40
41    type SerializeSeq = SeqSer;
42    type SerializeTuple = SeqSer;
43    type SerializeTupleStruct = SeqSer;
44    type SerializeTupleVariant = TupleVariantSer;
45    type SerializeMap = MapSer;
46    type SerializeStruct = MapSer;
47    type SerializeStructVariant = StructVariantSer;
48
49    fn serialize_bool(self, v: bool) -> Result<Out, Error> {
50        Ok(Some(Value::Bool(v)))
51    }
52
53    fn serialize_i8(self, v: i8) -> Result<Out, Error> {
54        Ok(Some(Value::I32(i32::from(v))))
55    }
56
57    fn serialize_i16(self, v: i16) -> Result<Out, Error> {
58        Ok(Some(Value::I32(i32::from(v))))
59    }
60
61    fn serialize_i32(self, v: i32) -> Result<Out, Error> {
62        Ok(Some(Value::I32(v)))
63    }
64
65    fn serialize_i64(self, _v: i64) -> Result<Out, Error> {
66        Err(Error::UnsupportedValue("i64"))
67    }
68
69    fn serialize_u8(self, v: u8) -> Result<Out, Error> {
70        Ok(Some(Value::U16(u16::from(v))))
71    }
72
73    fn serialize_u16(self, v: u16) -> Result<Out, Error> {
74        Ok(Some(Value::U16(v)))
75    }
76
77    fn serialize_u32(self, v: u32) -> Result<Out, Error> {
78        Ok(Some(Value::U32(v)))
79    }
80
81    fn serialize_u64(self, v: u64) -> Result<Out, Error> {
82        Ok(Some(Value::U64(v)))
83    }
84
85    fn serialize_u128(self, v: u128) -> Result<Out, Error> {
86        Ok(Some(Value::U128(v)))
87    }
88
89    fn serialize_f32(self, v: f32) -> Result<Out, Error> {
90        Ok(Some(Value::Float(v)))
91    }
92
93    fn serialize_f64(self, v: f64) -> Result<Out, Error> {
94        Ok(Some(Value::Double(v)))
95    }
96
97    fn serialize_char(self, v: char) -> Result<Out, Error> {
98        Ok(Some(Value::String(v.to_string())))
99    }
100
101    fn serialize_str(self, v: &str) -> Result<Out, Error> {
102        Ok(Some(Value::String(v.to_owned())))
103    }
104
105    fn serialize_bytes(self, v: &[u8]) -> Result<Out, Error> {
106        Ok(Some(Value::Bytes(v.to_vec())))
107    }
108
109    fn serialize_none(self) -> Result<Out, Error> {
110        Ok(None)
111    }
112
113    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Out, Error> {
114        value.serialize(self)
115    }
116
117    fn serialize_unit(self) -> Result<Out, Error> {
118        Ok(None)
119    }
120
121    fn serialize_unit_struct(self, _name: &'static str) -> Result<Out, Error> {
122        Ok(None)
123    }
124
125    fn serialize_unit_variant(
126        self,
127        _name: &'static str,
128        _variant_index: u32,
129        variant: &'static str,
130    ) -> Result<Out, Error> {
131        Ok(Some(Value::String(variant.to_owned())))
132    }
133
134    fn serialize_newtype_struct<T: ?Sized + Serialize>(
135        self,
136        _name: &'static str,
137        value: &T,
138    ) -> Result<Out, Error> {
139        value.serialize(self)
140    }
141
142    fn serialize_newtype_variant<T: ?Sized + Serialize>(
143        self,
144        _name: &'static str,
145        _variant_index: u32,
146        variant: &'static str,
147        value: &T,
148    ) -> Result<Out, Error> {
149        // Externally tagged: {"variant": value}.
150        let mut map = BTreeMap::new();
151        if let Some(v) = value.serialize(ValueSerializer)? {
152            map.insert(variant.to_owned(), v);
153        }
154        Ok(Some(Value::Map(map)))
155    }
156
157    fn serialize_seq(self, len: Option<usize>) -> Result<SeqSer, Error> {
158        Ok(SeqSer {
159            items: Vec::with_capacity(len.unwrap_or(0)),
160        })
161    }
162
163    fn serialize_tuple(self, len: usize) -> Result<SeqSer, Error> {
164        Ok(SeqSer {
165            items: Vec::with_capacity(len),
166        })
167    }
168
169    fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SeqSer, Error> {
170        Ok(SeqSer {
171            items: Vec::with_capacity(len),
172        })
173    }
174
175    fn serialize_tuple_variant(
176        self,
177        _name: &'static str,
178        _variant_index: u32,
179        variant: &'static str,
180        len: usize,
181    ) -> Result<TupleVariantSer, Error> {
182        Ok(TupleVariantSer {
183            variant,
184            items: Vec::with_capacity(len),
185        })
186    }
187
188    fn serialize_map(self, _len: Option<usize>) -> Result<MapSer, Error> {
189        Ok(MapSer {
190            entries: BTreeMap::new(),
191            pending_key: None,
192        })
193    }
194
195    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<MapSer, Error> {
196        Ok(MapSer {
197            entries: BTreeMap::new(),
198            pending_key: None,
199        })
200    }
201
202    fn serialize_struct_variant(
203        self,
204        _name: &'static str,
205        _variant_index: u32,
206        variant: &'static str,
207        _len: usize,
208    ) -> Result<StructVariantSer, Error> {
209        Ok(StructVariantSer {
210            variant,
211            entries: BTreeMap::new(),
212        })
213    }
214}
215
216pub(crate) struct SeqSer {
217    items: Vec<Value>,
218}
219
220impl SerializeSeq for SeqSer {
221    type Ok = Out;
222    type Error = Error;
223
224    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
225        if let Some(v) = value.serialize(ValueSerializer)? {
226            self.items.push(v);
227        }
228        Ok(())
229    }
230
231    fn end(self) -> Result<Out, Error> {
232        Ok(Some(Value::Array(self.items)))
233    }
234}
235
236impl SerializeTuple for SeqSer {
237    type Ok = Out;
238    type Error = Error;
239
240    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
241        SerializeSeq::serialize_element(self, value)
242    }
243
244    fn end(self) -> Result<Out, Error> {
245        SerializeSeq::end(self)
246    }
247}
248
249impl SerializeTupleStruct for SeqSer {
250    type Ok = Out;
251    type Error = Error;
252
253    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
254        SerializeSeq::serialize_element(self, value)
255    }
256
257    fn end(self) -> Result<Out, Error> {
258        SerializeSeq::end(self)
259    }
260}
261
262pub(crate) struct TupleVariantSer {
263    variant: &'static str,
264    items: Vec<Value>,
265}
266
267impl SerializeTupleVariant for TupleVariantSer {
268    type Ok = Out;
269    type Error = Error;
270
271    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
272        if let Some(v) = value.serialize(ValueSerializer)? {
273            self.items.push(v);
274        }
275        Ok(())
276    }
277
278    fn end(self) -> Result<Out, Error> {
279        let mut map = BTreeMap::new();
280        map.insert(self.variant.to_owned(), Value::Array(self.items));
281        Ok(Some(Value::Map(map)))
282    }
283}
284
285pub(crate) struct MapSer {
286    entries: BTreeMap<String, Value>,
287    pending_key: Option<String>,
288}
289
290impl SerializeMap for MapSer {
291    type Ok = Out;
292    type Error = Error;
293
294    fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), Error> {
295        let key_value = key
296            .serialize(ValueSerializer)?
297            .ok_or(Error::UnsupportedValue("null map key"))?;
298        let Value::String(k) = key_value else {
299            return Err(Error::UnsupportedValue("non-string map key"));
300        };
301        self.pending_key = Some(k);
302        Ok(())
303    }
304
305    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Error> {
306        let key = self.pending_key.take().ok_or(Error::UnsupportedValue(
307            "map value serialized before its key",
308        ))?;
309        if let Some(v) = value.serialize(ValueSerializer)? {
310            self.entries.insert(key, v);
311        }
312        // `None` → drop: this is how `Option::None` map values are skipped.
313        Ok(())
314    }
315
316    fn end(self) -> Result<Out, Error> {
317        Ok(Some(Value::Map(self.entries)))
318    }
319}
320
321impl SerializeStruct for MapSer {
322    type Ok = Out;
323    type Error = Error;
324
325    fn serialize_field<T: ?Sized + Serialize>(
326        &mut self,
327        key: &'static str,
328        value: &T,
329    ) -> Result<(), Error> {
330        if let Some(v) = value.serialize(ValueSerializer)? {
331            self.entries.insert(key.to_owned(), v);
332        }
333        Ok(())
334    }
335
336    fn end(self) -> Result<Out, Error> {
337        Ok(Some(Value::Map(self.entries)))
338    }
339}
340
341pub(crate) struct StructVariantSer {
342    variant: &'static str,
343    entries: BTreeMap<String, Value>,
344}
345
346impl SerializeStructVariant for StructVariantSer {
347    type Ok = Out;
348    type Error = Error;
349
350    fn serialize_field<T: ?Sized + Serialize>(
351        &mut self,
352        key: &'static str,
353        value: &T,
354    ) -> Result<(), Error> {
355        if let Some(v) = value.serialize(ValueSerializer)? {
356            self.entries.insert(key.to_owned(), v);
357        }
358        Ok(())
359    }
360
361    fn end(self) -> Result<Out, Error> {
362        let mut outer = BTreeMap::new();
363        outer.insert(self.variant.to_owned(), Value::Map(self.entries));
364        Ok(Some(Value::Map(outer)))
365    }
366}