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