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}