#[cfg(feature = "serde")]
mod serde {
use std::fmt;
use base64::{prelude::BASE64_STANDARD, Engine};
use serde::{de, ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer};
use crate::Any;
impl Serialize for Any {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("Any", 2)?;
state.serialize_field("@type", &self.type_url)?;
state.serialize_field("value", &BASE64_STANDARD.encode(&self.value))?;
state.end()
}
}
impl<'de> Deserialize<'de> for Any {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct AnyVisitor;
impl<'de> de::Visitor<'de> for AnyVisitor {
type Value = Any;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(
"struct Any with fields `@type` (string) and `value` (base64-encoded string)",
)
}
fn visit_map<V>(self, mut map: V) -> Result<Any, V::Error>
where
V: de::MapAccess<'de>,
{
let mut type_url: Option<String> = None;
let mut value_base64: Option<String> = None;
while let Some(key) = map.next_key::<String>()? {
match key.as_str() {
"@type" => {
if type_url.is_some() {
return Err(de::Error::duplicate_field("@type"));
}
type_url = Some(map.next_value()?);
}
"value" => {
if value_base64.is_some() {
return Err(de::Error::duplicate_field("value"));
}
value_base64 = Some(map.next_value()?);
}
_ => {
let _ = map.next_value::<de::IgnoredAny>()?;
}
}
}
let type_url = type_url.ok_or_else(|| de::Error::missing_field("@type"))?;
let value_base64 = value_base64.ok_or_else(|| de::Error::missing_field("value"))?;
let value = BASE64_STANDARD
.decode(&value_base64)
.map_err(de::Error::custom)?;
Ok(Any { type_url, value })
}
}
deserializer.deserialize_map(AnyVisitor) }
}
}