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 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}