pbjson_types/
value.rs

1pub use crate::pb::google::protobuf::value::Kind;
2
3use serde::{
4    Deserialize, Deserializer, Serialize, Serializer,
5    de::{self, MapAccess, SeqAccess},
6    ser,
7};
8
9macro_rules! from {
10    ($($typ: ty [$id:ident] => {$($from_type:ty => $exp:expr),+ $(,)?})+) => {
11        $($(
12            impl From<$from_type> for $typ {
13                #[allow(unused_variables)]
14                fn from($id: $from_type) -> Self {
15                    $exp
16                }
17            }
18        )+)+
19    }
20}
21
22from! {
23    crate::Value[value] => {
24        &'static str => Kind::from(value).into(),
25        () => Kind::NullValue(0).into(),
26        Kind => Self { kind: Some(value) },
27        Option<Kind> => Self { kind: value },
28        String => Kind::from(value).into(),
29        Vec<Self> => Kind::from(value).into(),
30        bool => Kind::from(value).into(),
31        crate::ListValue => Kind::from(value).into(),
32        crate::Struct => Kind::from(value).into(),
33        f64 => Kind::from(value).into(),
34        std::collections::HashMap<String, Self> => Kind::from(value).into(),
35    }
36
37    Kind[value] => {
38        &'static str => Self::StringValue(value.into()),
39        () => Self::NullValue(0),
40        String => Self::StringValue(value),
41        Vec<crate::Value> => Self::ListValue(value.into()),
42        bool => Self::BoolValue(value),
43        crate::ListValue => Self::ListValue(value),
44        crate::Struct => Self::StructValue(value),
45        f64 => Self::NumberValue(value),
46        std::collections::HashMap<String, crate::Value> => Self::StructValue(value.into()),
47    }
48}
49
50impl<const N: usize> From<[Self; N]> for crate::Value {
51    fn from(value: [Self; N]) -> Self {
52        crate::ListValue::from(value).into()
53    }
54}
55
56impl Serialize for crate::Value {
57    fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
58    where
59        S: Serializer,
60    {
61        self.kind.serialize(ser)
62    }
63}
64
65impl<'de> Deserialize<'de> for crate::Value {
66    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
67    where
68        D: Deserializer<'de>,
69    {
70        Ok(Self {
71            kind: <_>::deserialize(deserializer)?,
72        })
73    }
74}
75
76impl Serialize for Kind {
77    fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
78    where
79        S: Serializer,
80    {
81        match self {
82            Self::NullValue(_) => ().serialize(ser),
83            Self::StringValue(value) => value.serialize(ser),
84            Self::BoolValue(value) => value.serialize(ser),
85            Self::StructValue(value) => value.serialize(ser),
86            Self::ListValue(list) => list.serialize(ser),
87            Self::NumberValue(value) => {
88                // Kind does not allow NaN's or Infinity as they are
89                // indistinguishable from strings.
90                if value.is_nan() {
91                    Err(ser::Error::custom(
92                        "Cannot serialize NaN as google.protobuf.Value.number_value",
93                    ))
94                } else if value.is_infinite() {
95                    Err(ser::Error::custom(
96                        "Cannot serialize infinity as google.protobuf.Value.number_value",
97                    ))
98                } else {
99                    value.serialize(ser)
100                }
101            }
102        }
103    }
104}
105
106impl<'de> Deserialize<'de> for Kind {
107    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
108    where
109        D: Deserializer<'de>,
110    {
111        deserializer.deserialize_any(KindVisitor)
112    }
113}
114
115struct KindVisitor;
116
117impl<'de> serde::de::Visitor<'de> for KindVisitor {
118    type Value = Kind;
119
120    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121        formatter.write_str("google.protobuf.Value")
122    }
123
124    fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
125    where
126        E: de::Error,
127    {
128        Ok(Kind::BoolValue(v))
129    }
130
131    fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
132    where
133        E: de::Error,
134    {
135        Ok(Kind::NumberValue(v.into()))
136    }
137
138    fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
139    where
140        E: de::Error,
141    {
142        Ok(Kind::NumberValue(v.into()))
143    }
144
145    fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
146    where
147        E: de::Error,
148    {
149        Ok(Kind::NumberValue(v.into()))
150    }
151
152    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
153    where
154        E: de::Error,
155    {
156        if v > -(1 << f64::MANTISSA_DIGITS) && v < 1 << f64::MANTISSA_DIGITS {
157            return Ok(Kind::NumberValue(v as f64));
158        }
159
160        Err(de::Error::custom(
161            "out of range integral type conversion attempted",
162        ))
163    }
164
165    fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
166    where
167        E: de::Error,
168    {
169        self.visit_i64(v.try_into().map_err(de::Error::custom)?)
170    }
171
172    fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
173    where
174        E: de::Error,
175    {
176        Ok(Kind::NumberValue(v.into()))
177    }
178
179    fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
180    where
181        E: de::Error,
182    {
183        Ok(Kind::NumberValue(v.into()))
184    }
185
186    fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
187    where
188        E: de::Error,
189    {
190        Ok(Kind::NumberValue(v.into()))
191    }
192
193    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
194    where
195        E: de::Error,
196    {
197        if v < 1 << f64::MANTISSA_DIGITS {
198            return Ok(Kind::NumberValue(v as f64));
199        }
200
201        Err(de::Error::custom(
202            "out of range integral type conversion attempted",
203        ))
204    }
205
206    fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
207    where
208        E: de::Error,
209    {
210        self.visit_u64(v.try_into().map_err(de::Error::custom)?)
211    }
212
213    fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
214    where
215        E: de::Error,
216    {
217        Ok(Kind::NumberValue(v.into()))
218    }
219
220    fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
221    where
222        E: de::Error,
223    {
224        Ok(Kind::NumberValue(v))
225    }
226
227    fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
228    where
229        E: de::Error,
230    {
231        Ok(Kind::StringValue(v.into()))
232    }
233
234    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
235    where
236        E: de::Error,
237    {
238        Ok(Kind::StringValue(v.into()))
239    }
240
241    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
242    where
243        E: de::Error,
244    {
245        Ok(Kind::StringValue(v.into()))
246    }
247
248    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
249    where
250        E: de::Error,
251    {
252        Ok(Kind::StringValue(v))
253    }
254
255    fn visit_none<E>(self) -> Result<Self::Value, E>
256    where
257        E: de::Error,
258    {
259        Ok(Kind::NullValue(0))
260    }
261
262    fn visit_some<D>(self, de: D) -> Result<Self::Value, D::Error>
263    where
264        D: Deserializer<'de>,
265    {
266        Deserialize::deserialize(de)
267    }
268
269    fn visit_unit<E>(self) -> Result<Self::Value, E>
270    where
271        E: de::Error,
272    {
273        Ok(Kind::NullValue(0))
274    }
275
276    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
277    where
278        A: SeqAccess<'de>,
279    {
280        let mut list = Vec::new();
281
282        while let Some(value) = seq.next_element()? {
283            list.push(value);
284        }
285
286        Ok(Kind::ListValue(list.into()))
287    }
288
289    fn visit_map<A>(self, mut map_access: A) -> Result<Self::Value, A::Error>
290    where
291        A: MapAccess<'de>,
292    {
293        let mut map = std::collections::HashMap::new();
294
295        while let Some((key, value)) = map_access.next_entry()? {
296            map.insert(key, value);
297        }
298
299        Ok(Kind::StructValue(map.into()))
300    }
301}
302
303#[cfg(test)]
304mod tests {
305    use crate::Value;
306
307    #[test]
308    fn boolean() {
309        assert_eq!(
310            serde_json::to_value(Value::from(false)).unwrap(),
311            serde_json::json!(false)
312        );
313        assert_eq!(
314            serde_json::to_value(Value::from(true)).unwrap(),
315            serde_json::json!(true)
316        );
317    }
318
319    #[test]
320    fn number() {
321        assert_eq!(
322            serde_json::to_value(Value::from(5.0)).unwrap(),
323            serde_json::json!(5.0)
324        );
325    }
326
327    #[test]
328    fn string() {
329        assert_eq!(
330            serde_json::to_value(Value::from("string")).unwrap(),
331            serde_json::json!("string")
332        );
333    }
334
335    #[test]
336    fn float_special_cases() {
337        assert!(serde_json::to_value(Value::from(f64::NAN)).is_err());
338        assert!(serde_json::to_value(Value::from(f64::INFINITY)).is_err());
339        assert!(serde_json::to_value(Value::from(f64::NEG_INFINITY)).is_err());
340    }
341
342    #[test]
343    fn parse_max_safe_integer() {
344        let max_safe_integer: i64 = 9007199254740991;
345        let json = serde_json::json!(max_safe_integer);
346        let vec = serde_json::to_vec(&json).unwrap();
347        let pb = serde_json::from_slice::<Value>(&vec).unwrap();
348        assert_eq!(
349            serde_json::to_value(pb).unwrap(),
350            serde_json::json!(max_safe_integer as f64)
351        );
352    }
353
354    #[test]
355    fn parse_min_safe_integer() {
356        let min_safe_integer: i64 = -9007199254740991;
357        let json = serde_json::json!(min_safe_integer);
358        let vec = serde_json::to_vec(&json).unwrap();
359        let pb = serde_json::from_slice::<Value>(&vec).unwrap();
360        assert_eq!(
361            serde_json::to_value(pb).unwrap(),
362            serde_json::json!(min_safe_integer as f64)
363        );
364    }
365}