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}