#[doc(hidden)]
#[macro_export]
macro_rules! impl_string_serde {
($ty:ty, $name:expr) => {
impl ::serde::Serialize for $ty {
fn serialize<S: ::serde::Serializer>(
&self,
s: S,
) -> ::core::result::Result<S::Ok, S::Error> {
s.collect_str(self)
}
}
impl<'de> ::serde::Deserialize<'de> for $ty {
fn deserialize<D: ::serde::Deserializer<'de>>(
d: D,
) -> ::core::result::Result<Self, D::Error> {
let raw = <::std::string::String as ::serde::Deserialize>::deserialize(d)?;
raw.parse().map_err(|e: $crate::ParseError| {
::serde::de::Error::custom(format!("{}: {}", $name, e.reason))
})
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_valued_serde {
($ty:ty, $name:literal) => {
impl ::serde::Serialize for $ty {
fn serialize<S: ::serde::Serializer>(
&self,
s: S,
) -> ::core::result::Result<S::Ok, S::Error> {
use ::serde::ser::SerializeStruct as _;
let mut st = s.serialize_struct($name, 2)?;
st.serialize_field("_type", $name)?;
st.serialize_field("value", &self.to_string())?;
st.end()
}
}
impl<'de> ::serde::Deserialize<'de> for $ty {
fn deserialize<D: ::serde::Deserializer<'de>>(
d: D,
) -> ::core::result::Result<Self, D::Error> {
let raw = $crate::base::serde_support::ValuedId::deserialize_checked(d, $name)?;
raw.parse().map_err(|e: $crate::ParseError| {
::serde::de::Error::custom(format!("{}: {}", $name, e.reason))
})
}
}
};
}
#[doc(hidden)]
pub struct ValuedId;
impl ValuedId {
#[doc(hidden)]
pub fn deserialize_checked<'de, D: serde::Deserializer<'de>>(
d: D,
expected: &'static str,
) -> Result<String, D::Error> {
use serde::de::{Error as _, MapAccess, Visitor};
struct V(&'static str);
impl<'de> Visitor<'de> for V {
type Value = String;
fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "a string or a {{\"value\": …}} object for {}", self.0)
}
fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<String, E> {
Ok(v.to_owned())
}
fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<String, A::Error> {
let mut value: Option<String> = None;
while let Some(key) = map.next_key::<String>()? {
match key.as_str() {
"value" => value = Some(map.next_value()?),
"_type" => {
let ty: String = map.next_value()?;
if ty != self.0 {
return Err(A::Error::custom(format!(
"_type is {ty}, expected {}",
self.0
)));
}
}
_ => {
map.next_value::<serde::de::IgnoredAny>()?;
}
}
}
value.ok_or_else(|| A::Error::missing_field("value"))
}
}
d.deserialize_any(V(expected))
}
}