Skip to main content

mmdb_writer/value/
serde_impls.rs

1//! `Serialize`/`Deserialize` for [`Value`], gated on the `serde` feature.
2//!
3//! A `Value` serializes *as* the data it holds (a [`Value::String`] serializes as a string,
4//! a [`Value::Map`] as a map) rather than as a tagged enum, and deserializes from arbitrary
5//! self-describing data into the closest-fitting variant. The `Deserialize` side is what
6//! lets [`Writer::load`] rebuild values from an existing database.
7//!
8//! [`Writer::load`]: crate::Writer::load
9
10use std::collections::BTreeMap;
11use std::fmt;
12
13use serde::de::{self, Deserializer, MapAccess, SeqAccess, Visitor};
14use serde::ser::{SerializeMap, SerializeSeq, Serializer};
15use serde::{Deserialize, Serialize};
16
17use super::Value;
18
19impl Serialize for Value {
20    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
21        match self {
22            Value::String(s) => serializer.serialize_str(s),
23            Value::Double(d) => serializer.serialize_f64(*d),
24            Value::Bytes(b) => serializer.serialize_bytes(b),
25            Value::U16(n) => serializer.serialize_u16(*n),
26            Value::U32(n) => serializer.serialize_u32(*n),
27            Value::I32(n) => serializer.serialize_i32(*n),
28            Value::U64(n) => serializer.serialize_u64(*n),
29            Value::U128(n) => serializer.serialize_u128(*n),
30            Value::Bool(b) => serializer.serialize_bool(*b),
31            Value::Float(f) => serializer.serialize_f32(*f),
32            Value::Map(m) => {
33                let mut map = serializer.serialize_map(Some(m.len()))?;
34                for (k, v) in m {
35                    map.serialize_entry(k, v)?;
36                }
37                map.end()
38            }
39            Value::Array(items) => {
40                let mut seq = serializer.serialize_seq(Some(items.len()))?;
41                for item in items {
42                    seq.serialize_element(item)?;
43                }
44                seq.end()
45            }
46        }
47    }
48}
49
50impl<'de> Deserialize<'de> for Value {
51    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
52        deserializer.deserialize_any(ValueVisitor)
53    }
54}
55
56struct ValueVisitor;
57
58impl<'de> Visitor<'de> for ValueVisitor {
59    type Value = Value;
60
61    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        f.write_str("any MMDB-representable value")
63    }
64
65    fn visit_bool<E: de::Error>(self, v: bool) -> Result<Value, E> {
66        Ok(Value::Bool(v))
67    }
68
69    fn visit_i8<E: de::Error>(self, v: i8) -> Result<Value, E> {
70        Ok(Value::I32(i32::from(v)))
71    }
72
73    fn visit_i16<E: de::Error>(self, v: i16) -> Result<Value, E> {
74        Ok(Value::I32(i32::from(v)))
75    }
76
77    fn visit_i32<E: de::Error>(self, v: i32) -> Result<Value, E> {
78        Ok(Value::I32(v))
79    }
80
81    fn visit_i64<E: de::Error>(self, v: i64) -> Result<Value, E> {
82        // MMDB has no signed 64-bit type; accept values that fit int32, reject the rest.
83        i32::try_from(v)
84            .map(Value::I32)
85            .map_err(|_| de::Error::custom("i64 outside int32 range has no MMDB representation"))
86    }
87
88    fn visit_u8<E: de::Error>(self, v: u8) -> Result<Value, E> {
89        Ok(Value::U16(u16::from(v)))
90    }
91
92    fn visit_u16<E: de::Error>(self, v: u16) -> Result<Value, E> {
93        Ok(Value::U16(v))
94    }
95
96    fn visit_u32<E: de::Error>(self, v: u32) -> Result<Value, E> {
97        Ok(Value::U32(v))
98    }
99
100    fn visit_u64<E: de::Error>(self, v: u64) -> Result<Value, E> {
101        Ok(Value::U64(v))
102    }
103
104    fn visit_u128<E: de::Error>(self, v: u128) -> Result<Value, E> {
105        Ok(Value::U128(v))
106    }
107
108    fn visit_f32<E: de::Error>(self, v: f32) -> Result<Value, E> {
109        Ok(Value::Float(v))
110    }
111
112    fn visit_f64<E: de::Error>(self, v: f64) -> Result<Value, E> {
113        Ok(Value::Double(v))
114    }
115
116    fn visit_str<E: de::Error>(self, v: &str) -> Result<Value, E> {
117        Ok(Value::String(v.to_owned()))
118    }
119
120    fn visit_string<E: de::Error>(self, v: String) -> Result<Value, E> {
121        Ok(Value::String(v))
122    }
123
124    fn visit_bytes<E: de::Error>(self, v: &[u8]) -> Result<Value, E> {
125        Ok(Value::Bytes(v.to_vec()))
126    }
127
128    fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> Result<Value, E> {
129        Ok(Value::Bytes(v))
130    }
131
132    fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Value, A::Error> {
133        let mut items = Vec::with_capacity(seq.size_hint().unwrap_or(0));
134        while let Some(item) = seq.next_element()? {
135            items.push(item);
136        }
137        Ok(Value::Array(items))
138    }
139
140    fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Value, A::Error> {
141        let mut entries = BTreeMap::new();
142        while let Some((k, v)) = map.next_entry::<String, Value>()? {
143            entries.insert(k, v);
144        }
145        Ok(Value::Map(entries))
146    }
147}