prost_wkt_types/
pbstruct.rs

1use serde::de::{self, Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
2use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer};
3
4use std::borrow::Cow;
5use std::convert::TryFrom;
6use std::fmt;
7
8include!(concat!(env!("OUT_DIR"), "/pbstruct/google.protobuf.rs"));
9
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct ValueError {
12    description: Cow<'static, str>,
13}
14
15impl ValueError {
16    pub fn new<S>(description: S) -> Self
17    where
18        S: Into<Cow<'static, str>>,
19    {
20        ValueError {
21            description: description.into(),
22        }
23    }
24}
25
26impl std::error::Error for ValueError {
27    fn description(&self) -> &str {
28        &self.description
29    }
30}
31
32impl std::fmt::Display for ValueError {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        f.write_str("failed to convert Value: ")?;
35        f.write_str(&self.description)
36    }
37}
38
39impl Value {
40    pub fn null() -> Self {
41        let kind = Some(value::Kind::NullValue(0));
42        Value { kind }
43    }
44    pub fn number(num: f64) -> Self {
45        Value::from(num)
46    }
47    pub fn string(s: String) -> Self {
48        Value::from(s)
49    }
50    pub fn bool(b: bool) -> Self {
51        Value::from(b)
52    }
53    pub fn pb_struct(m: std::collections::HashMap<std::string::String, Value>) -> Self {
54        Value::from(m)
55    }
56    pub fn pb_list(l: std::vec::Vec<Value>) -> Self {
57        Value::from(l)
58    }
59}
60
61impl From<NullValue> for Value {
62    fn from(_: NullValue) -> Self {
63        Value::null()
64    }
65}
66
67impl From<f64> for Value {
68    fn from(num: f64) -> Self {
69        let kind = Some(value::Kind::NumberValue(num));
70        Value { kind }
71    }
72}
73
74impl TryFrom<Value> for f64 {
75    type Error = ValueError;
76
77    fn try_from(value: Value) -> Result<Self, Self::Error> {
78        match value.kind {
79            Some(value::Kind::NumberValue(num)) => Ok(num),
80            Some(_other) => Err(ValueError::new(
81                "Cannot convert to f64 because this is not a ValueNumber.",
82            )),
83            _ => Err(ValueError::new(
84                "Conversion to f64 failed because value is empty!",
85            )),
86        }
87    }
88}
89
90impl From<String> for Value {
91    fn from(s: String) -> Self {
92        let kind = Some(value::Kind::StringValue(s));
93        Value { kind }
94    }
95}
96
97impl TryFrom<Value> for String {
98    type Error = ValueError;
99
100    fn try_from(value: Value) -> Result<Self, Self::Error> {
101        match value.kind {
102            Some(value::Kind::StringValue(string)) => Ok(string),
103            Some(_other) => Err(ValueError::new(
104                "Cannot convert to String because this is not a StringValue.",
105            )),
106            _ => Err(ValueError::new(
107                "Conversion to String failed because value is empty!",
108            )),
109        }
110    }
111}
112
113impl From<bool> for Value {
114    fn from(b: bool) -> Self {
115        let kind = Some(value::Kind::BoolValue(b));
116        Value { kind }
117    }
118}
119
120impl TryFrom<Value> for bool {
121    type Error = ValueError;
122
123    fn try_from(value: Value) -> Result<Self, Self::Error> {
124        match value.kind {
125            Some(value::Kind::BoolValue(b)) => Ok(b),
126            Some(_other) => Err(ValueError::new(
127                "Cannot convert to bool because this is not a BoolValue.",
128            )),
129            _ => Err(ValueError::new(
130                "Conversion to bool failed because value is empty!",
131            )),
132        }
133    }
134}
135
136impl From<std::collections::HashMap<std::string::String, Value>> for Value {
137    fn from(fields: std::collections::HashMap<String, Value>) -> Self {
138        let s = Struct { fields };
139        let kind = Some(value::Kind::StructValue(s));
140        Value { kind }
141    }
142}
143
144impl TryFrom<Value> for std::collections::HashMap<std::string::String, Value> {
145    type Error = ValueError;
146
147    fn try_from(value: Value) -> Result<Self, Self::Error> {
148        match value.kind {
149            Some(value::Kind::StructValue(s)) => Ok(s.fields),
150            Some(_other) => Err(ValueError::new(
151                "Cannot convert to HashMap<String, Value> because this is not a StructValue.",
152            )),
153            _ => Err(ValueError::new(
154                "Conversion to HashMap<String, Value> failed because value is empty!",
155            )),
156        }
157    }
158}
159
160impl From<std::vec::Vec<Value>> for Value {
161    fn from(values: Vec<Value>) -> Self {
162        let v = ListValue { values };
163        let kind = Some(value::Kind::ListValue(v));
164        Value { kind }
165    }
166}
167
168impl TryFrom<Value> for std::vec::Vec<Value> {
169    type Error = ValueError;
170
171    fn try_from(value: Value) -> Result<Self, Self::Error> {
172        match value.kind {
173            Some(value::Kind::ListValue(list)) => Ok(list.values),
174            Some(_other) => Err(ValueError::new(
175                "Cannot convert to Vec<Value> because this is not a ListValue.",
176            )),
177            _ => Err(ValueError::new(
178                "Conversion to Vec<Value> failed because value is empty!",
179            )),
180        }
181    }
182}
183
184impl Serialize for ListValue {
185    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
186    where
187        S: Serializer,
188    {
189        let mut seq = serializer.serialize_seq(Some(self.values.len()))?;
190        for e in &self.values {
191            seq.serialize_element(e)?;
192        }
193        seq.end()
194    }
195}
196
197impl Serialize for Struct {
198    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
199    where
200        S: Serializer,
201    {
202        let mut map = serializer.serialize_map(Some(self.fields.len()))?;
203        for (k, v) in &self.fields {
204            map.serialize_entry( k, v)?;
205        }
206        map.end()
207    }
208}
209
210impl Serialize for Value {
211    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
212    where
213        S: Serializer,
214    {
215        match &self.kind {
216            Some(value::Kind::NumberValue(num)) => serializer.serialize_f64(*num),
217            Some(value::Kind::StringValue(string)) => serializer.serialize_str(string),
218            Some(value::Kind::BoolValue(boolean)) => serializer.serialize_bool(*boolean),
219            Some(value::Kind::NullValue(_)) => serializer.serialize_none(),
220            Some(value::Kind::ListValue(list)) => {
221                list.serialize(serializer)
222            }
223            Some(value::Kind::StructValue(object)) => {
224                object.serialize(serializer)
225            }
226            _ => serializer.serialize_none(),
227        }
228    }
229}
230
231struct ListValueVisitor;
232impl<'de> Visitor<'de> for ListValueVisitor {
233    type Value = crate::ListValue;
234
235    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
236        formatter.write_str("a prost_wkt_types::ListValue struct")
237    }
238
239    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
240    where
241        A: SeqAccess<'de>,
242    {
243        let mut values: Vec<Value> = Vec::new();
244        while let Some(el) = seq.next_element()? {
245            values.push(el)
246        }
247        Ok(ListValue {
248            values
249        })
250    }
251}
252
253impl<'de> Deserialize<'de> for ListValue {
254    fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
255    where
256        D: Deserializer<'de>,
257    {
258        deserializer.deserialize_seq(ListValueVisitor)
259    }
260}
261
262struct StructVisitor;
263impl<'de> Visitor<'de> for StructVisitor {
264    type Value = crate::Struct;
265
266    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
267        formatter.write_str("a prost_wkt_types::Struct struct")
268    }
269
270    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
271    where
272        A: MapAccess<'de>,
273    {
274        let mut fields: std::collections::HashMap<String, Value> =
275            std::collections::HashMap::new();
276        while let Some((key, value)) = map.next_entry::<String, Value>()? {
277            fields.insert(key, value);
278        }
279        Ok(Struct {
280            fields
281        })
282    }
283}
284
285impl<'de> Deserialize<'de> for Struct {
286    fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
287        where
288            D: Deserializer<'de> {
289        deserializer.deserialize_map(StructVisitor)
290    }
291}
292
293impl<'de> Deserialize<'de> for Value {
294    fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
295    where
296        D: Deserializer<'de>,
297    {
298        struct ValueVisitor;
299
300        impl<'de> Visitor<'de> for ValueVisitor {
301            type Value = crate::Value;
302
303            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
304                formatter.write_str("a prost_wkt_types::Value struct")
305            }
306
307            fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
308            where
309                E: de::Error,
310            {
311                Ok(Value::from(value))
312            }
313
314            fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
315            where
316                E: de::Error,
317            {
318                Ok(Value::from(value as f64))
319            }
320
321            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
322            where
323                E: de::Error,
324            {
325                Ok(Value::from(value as f64))
326            }
327
328            fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
329            where
330                E: de::Error,
331            {
332                Ok(Value::from(value))
333            }
334
335            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
336            where
337                E: de::Error,
338            {
339                Ok(Value::from(String::from(value)))
340            }
341
342            fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
343            where
344                E: de::Error,
345            {
346                Ok(Value::from(value))
347            }
348
349            fn visit_none<E>(self) -> Result<Self::Value, E>
350            where
351                E: de::Error,
352            {
353                Ok(Value::null())
354            }
355
356            fn visit_unit<E>(self) -> Result<Self::Value, E>
357            where
358                E: de::Error,
359            {
360                Ok(Value::null())
361            }
362
363            fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
364            where
365                A: SeqAccess<'de>,
366            {
367                ListValueVisitor.visit_seq(seq).map(|lv| {
368                    let kind = Some(value::Kind::ListValue(lv));
369                    Value { kind }
370                })
371            }
372
373            fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
374            where
375                A: MapAccess<'de>,
376            {
377                StructVisitor.visit_map(map).map(|s| {
378                    let kind = Some(value::Kind::StructValue(s));
379                    Value { kind }
380                })
381            }
382        }
383        deserializer.deserialize_any(ValueVisitor)
384    }
385}
386
387#[cfg(test)]
388mod tests {
389    use crate::pbstruct::*;
390    use std::collections::HashMap;
391
392    #[test]
393    fn conversion_test() {
394        let number: Value = Value::from(10.0);
395        println!("Number: {number:?}");
396        let null: Value = Value::null();
397        println!("Null: {null:?}");
398        let string: Value = Value::from(String::from("Hello"));
399        println!("String: {string:?}");
400        let list = vec![Value::null(), Value::from(100.0)];
401        let pb_list: Value = Value::from(list);
402        println!("List: {pb_list:?}");
403        let mut map: HashMap<String, Value> = HashMap::new();
404        map.insert(String::from("some_number"), number);
405        map.insert(String::from("a_null_value"), null);
406        map.insert(String::from("string"), string);
407        map.insert(String::from("list"), pb_list);
408        let pb_struct: Value = Value::from(map);
409        println!("Struct: {pb_struct:?}");
410    }
411
412    #[test]
413    fn convert_serde_json_test() {
414        let data = r#"{
415            "string":"hello",
416            "timestamp":"1970-01-01T00:01:39.000000042Z",
417            "boolean":true,
418            "data": {
419              "test_number": 1.0,
420              "test_bool": true,
421              "testString": "hi there",
422              "testList": [1.0, 2.0, 3.0, 4.0],
423              "testInnerStruct": {
424                "one": 1.0,
425                "two": 2.0
426              }
427            },
428            "list": []
429          }"#;
430        let sj: serde_json::Value = serde_json::from_str(data).unwrap();
431        println!("serde_json::Value: {sj:#?}");
432        let pj: Value = serde_json::from_value(sj.clone()).unwrap();
433        let string: String = serde_json::to_string_pretty(&pj).unwrap();
434        println!("prost_wkt_types String: {string}");
435        let back: serde_json::Value = serde_json::from_str(&string).unwrap();
436        assert_eq!(sj, back);
437    }
438}