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)) => list.serialize(serializer),
221            Some(value::Kind::StructValue(object)) => object.serialize(serializer),
222            _ => serializer.serialize_none(),
223        }
224    }
225}
226
227struct ListValueVisitor;
228impl<'de> Visitor<'de> for ListValueVisitor {
229    type Value = crate::ListValue;
230
231    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
232        formatter.write_str("a prost_wkt_types::ListValue struct")
233    }
234
235    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
236    where
237        A: SeqAccess<'de>,
238    {
239        let mut values: Vec<Value> = Vec::new();
240        while let Some(el) = seq.next_element()? {
241            values.push(el)
242        }
243        Ok(ListValue { values })
244    }
245}
246
247impl<'de> Deserialize<'de> for ListValue {
248    fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
249    where
250        D: Deserializer<'de>,
251    {
252        deserializer.deserialize_seq(ListValueVisitor)
253    }
254}
255
256struct StructVisitor;
257impl<'de> Visitor<'de> for StructVisitor {
258    type Value = crate::Struct;
259
260    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
261        formatter.write_str("a prost_wkt_types::Struct struct")
262    }
263
264    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
265    where
266        A: MapAccess<'de>,
267    {
268        let mut fields: std::collections::HashMap<String, Value> = std::collections::HashMap::new();
269        while let Some((key, value)) = map.next_entry::<String, Value>()? {
270            fields.insert(key, value);
271        }
272        Ok(Struct { fields })
273    }
274}
275
276impl<'de> Deserialize<'de> for Struct {
277    fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
278    where
279        D: Deserializer<'de>,
280    {
281        deserializer.deserialize_map(StructVisitor)
282    }
283}
284
285impl<'de> Deserialize<'de> for Value {
286    fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
287    where
288        D: Deserializer<'de>,
289    {
290        struct ValueVisitor;
291
292        impl<'de> Visitor<'de> for ValueVisitor {
293            type Value = crate::Value;
294
295            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
296                formatter.write_str("a prost_wkt_types::Value struct")
297            }
298
299            fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
300            where
301                E: de::Error,
302            {
303                Ok(Value::from(value))
304            }
305
306            fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
307            where
308                E: de::Error,
309            {
310                Ok(Value::from(value as f64))
311            }
312
313            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
314            where
315                E: de::Error,
316            {
317                Ok(Value::from(value as f64))
318            }
319
320            fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
321            where
322                E: de::Error,
323            {
324                Ok(Value::from(value))
325            }
326
327            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
328            where
329                E: de::Error,
330            {
331                Ok(Value::from(String::from(value)))
332            }
333
334            fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
335            where
336                E: de::Error,
337            {
338                Ok(Value::from(value))
339            }
340
341            fn visit_none<E>(self) -> Result<Self::Value, E>
342            where
343                E: de::Error,
344            {
345                Ok(Value::null())
346            }
347
348            fn visit_unit<E>(self) -> Result<Self::Value, E>
349            where
350                E: de::Error,
351            {
352                Ok(Value::null())
353            }
354
355            fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
356            where
357                A: SeqAccess<'de>,
358            {
359                ListValueVisitor.visit_seq(seq).map(|lv| {
360                    let kind = Some(value::Kind::ListValue(lv));
361                    Value { kind }
362                })
363            }
364
365            fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
366            where
367                A: MapAccess<'de>,
368            {
369                StructVisitor.visit_map(map).map(|s| {
370                    let kind = Some(value::Kind::StructValue(s));
371                    Value { kind }
372                })
373            }
374        }
375        deserializer.deserialize_any(ValueVisitor)
376    }
377}
378
379#[cfg(test)]
380mod tests {
381    use crate::pbstruct::*;
382    use std::collections::HashMap;
383
384    #[test]
385    fn conversion_test() {
386        let number: Value = Value::from(10.0);
387        println!("Number: {number:?}");
388        let null: Value = Value::null();
389        println!("Null: {null:?}");
390        let string: Value = Value::from(String::from("Hello"));
391        println!("String: {string:?}");
392        let list = vec![Value::null(), Value::from(100.0)];
393        let pb_list: Value = Value::from(list);
394        println!("List: {pb_list:?}");
395        let mut map: HashMap<String, Value> = HashMap::new();
396        map.insert(String::from("some_number"), number);
397        map.insert(String::from("a_null_value"), null);
398        map.insert(String::from("string"), string);
399        map.insert(String::from("list"), pb_list);
400        let pb_struct: Value = Value::from(map);
401        println!("Struct: {pb_struct:?}");
402    }
403
404    #[test]
405    fn convert_serde_json_test() {
406        let data = r#"{
407            "string":"hello",
408            "timestamp":"1970-01-01T00:01:39.000000042Z",
409            "boolean":true,
410            "data": {
411              "test_number": 1.0,
412              "test_bool": true,
413              "testString": "hi there",
414              "testList": [1.0, 2.0, 3.0, 4.0],
415              "testInnerStruct": {
416                "one": 1.0,
417                "two": 2.0
418              }
419            },
420            "list": []
421          }"#;
422        let sj: serde_json::Value = serde_json::from_str(data).unwrap();
423        println!("serde_json::Value: {sj:#?}");
424        let pj: Value = serde_json::from_value(sj.clone()).unwrap();
425        let string: String = serde_json::to_string_pretty(&pj).unwrap();
426        println!("prost_wkt_types String: {string}");
427        let back: serde_json::Value = serde_json::from_str(&string).unwrap();
428        assert_eq!(sj, back);
429    }
430}