proto_types/
any_impls.rs

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      // Define a visitor to expect a map (JSON object)
28      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          // Loop through fields, expecting "@type" and "value"
47          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                // Ignore any other fields
63                let _ = map.next_value::<de::IgnoredAny>()?;
64              }
65            }
66          }
67
68          // Check that required fields were present
69          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          // Decode base64 value
73          let value = BASE64_STANDARD
74            .decode(&value_base64)
75            .map_err(de::Error::custom)?;
76
77          Ok(Any { type_url, value })
78        }
79
80        // If the JSON is not an object (e.g., if it was an unwrapped WKT like a string),
81        // this minimal implementation will just return an error.
82      }
83
84      deserializer.deserialize_map(AnyVisitor) // Instruct serde to expect a map/object
85    }
86  }
87}