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