use std::fmt;
use std::marker::PhantomData;
use std::str::FromStr;
use serde::de::{
self,
Visitor
};
pub struct FromStrVisitor<T>{
expect: &'static str,
marker: PhantomData<T>
}
impl<T> FromStrVisitor<T> {
pub fn expect(expect: &'static str) -> Self {
let marker = PhantomData;
Self { expect, marker }
}
}
impl<'de, T, E> Visitor<'de> for FromStrVisitor<T>
where T: FromStr<Err = E>,
E: fmt::Display
{
type Value = T;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(self.expect)
}
fn visit_str<D>(self, value: &str) -> Result<Self::Value, D>
where D: de::Error,
{
value.parse::<T>().map_err(D::custom)
}
}
macro_rules! serde_as_str {
($t:ty, $e:literal) => {
impl serde::Serialize for $t {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer
{
serializer.serialize_str(&self.to_string())
}
}
impl<'de> serde::Deserialize<'de> for $t {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::Deserializer<'de>
{
deserializer.deserialize_str(
$crate::util::serde::FromStrVisitor::expect($e)
)
}
}
};
}