pbjson_types/
value.rs

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