1#[cfg(feature = "serde")]
2mod serde {
3 use std::fmt;
4
5 use base64::{prelude::BASE64_STANDARD, Engine};
6 use serde::{de, ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer};
7
8 use crate::Any;
9
10 impl Serialize for Any {
11 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
12 where
13 S: Serializer,
14 {
15 let mut state = serializer.serialize_struct("Any", 2)?;
16 state.serialize_field("@type", &self.type_url)?;
17 state.serialize_field("value", &BASE64_STANDARD.encode(&self.value))?;
18 state.end()
19 }
20 }
21
22 impl<'de> Deserialize<'de> for Any {
23 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
24 where
25 D: Deserializer<'de>,
26 {
27 struct AnyVisitor;
29
30 impl<'de> de::Visitor<'de> for AnyVisitor {
31 type Value = Any;
32
33 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
34 formatter.write_str(
35 "struct Any with fields `@type` (string) and `value` (base64-encoded string)",
36 )
37 }
38
39 fn visit_map<V>(self, mut map: V) -> Result<Any, V::Error>
40 where
41 V: de::MapAccess<'de>,
42 {
43 let mut type_url: Option<String> = None;
44 let mut value_base64: Option<String> = None;
45
46 while let Some(key) = map.next_key::<String>()? {
48 match key.as_str() {
49 "@type" => {
50 if type_url.is_some() {
51 return Err(de::Error::duplicate_field("@type"));
52 }
53 type_url = Some(map.next_value()?);
54 }
55 "value" => {
56 if value_base64.is_some() {
57 return Err(de::Error::duplicate_field("value"));
58 }
59 value_base64 = Some(map.next_value()?);
60 }
61 _ => {
62 let _ = map.next_value::<de::IgnoredAny>()?;
64 }
65 }
66 }
67
68 let type_url = type_url.ok_or_else(|| de::Error::missing_field("@type"))?;
70 let value_base64 = value_base64.ok_or_else(|| de::Error::missing_field("value"))?;
71
72 let value = BASE64_STANDARD
74 .decode(&value_base64)
75 .map_err(de::Error::custom)?;
76
77 Ok(Any { type_url, value })
78 }
79
80 }
83
84 deserializer.deserialize_map(AnyVisitor) }
86 }
87}