use std::{
fmt::{self, Display},
marker::PhantomData,
str::FromStr,
};
use serde::de::{Deserializer, Visitor};
pub fn from_str<'de, D, T>(deserializer: D) -> Result<T, D::Error>
where
D: Deserializer<'de>,
T: FromStr,
T::Err: Display,
{
deserializer.deserialize_str(FromStrVisitor { ty: PhantomData })
}
struct FromStrVisitor<T> {
ty: PhantomData<T>,
}
impl<'de, T> Visitor<'de> for FromStrVisitor<T>
where
T: FromStr,
T::Err: Display,
{
type Value = T;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
formatter,
"type {} in its text form",
std::any::type_name::<T>()
)
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
v.parse().map_err(E::custom)
}
}