use core::fmt; use core::marker::PhantomData; use core::str::{self, FromStr}; use serde::de; /// A serde visitor that works for `T`s implementing `FromStr`. pub struct FromStrVisitor { expectation: &'static str, _pd: PhantomData, } impl FromStrVisitor { pub fn new(expectation: &'static str) -> Self { FromStrVisitor { expectation, _pd: PhantomData, } } } impl<'de, T> de::Visitor<'de> for FromStrVisitor where T: FromStr, ::Err: fmt::Display, { type Value = T; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str(self.expectation) } fn visit_str(self, v: &str) -> Result { FromStr::from_str(v).map_err(E::custom) } } pub struct BytesVisitor { expectation: &'static str, parse_fn: F, } impl BytesVisitor where F: FnOnce(&[u8]) -> Result, Err: fmt::Display, { pub fn new(expectation: &'static str, parse_fn: F) -> Self { BytesVisitor { expectation, parse_fn, } } } impl<'de, F, T, Err> de::Visitor<'de> for BytesVisitor where F: FnOnce(&[u8]) -> Result, Err: fmt::Display, { type Value = T; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str(self.expectation) } fn visit_bytes(self, v: &[u8]) -> Result { (self.parse_fn)(v).map_err(E::custom) } }