use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt::{Display, Formatter}; use std::ops::Deref; use std::str::FromStr; /// Preserves the verbatim string representation when deserializing `T`. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub(crate) struct SerdeVerbatim { verbatim: String, inner: T, } impl SerdeVerbatim { pub(crate) fn verbatim(&self) -> &str { &self.verbatim } } impl Deref for SerdeVerbatim { type Target = T; fn deref(&self) -> &Self::Target { &self.inner } } impl Display for SerdeVerbatim { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.inner.fmt(f) } } impl<'de, T: FromStr> Deserialize<'de> for SerdeVerbatim where ::Err: Display, { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { let verbatim = String::deserialize(deserializer)?; let inner = T::from_str(&verbatim).map_err(serde::de::Error::custom)?; Ok(Self { verbatim, inner }) } } impl Serialize for SerdeVerbatim { fn serialize(&self, serializer: S) -> Result where S: Serializer, { self.inner.serialize(serializer) } }