#[doc(hidden)]
#[macro_export]
macro_rules! impl_try_from_stringly {
($from:ty, $to:ty, $error:ty, $func:expr) => {
$(#[$attr])?
impl core::convert::TryFrom<$from> for $to {
type Error = $error;
fn try_from(s: $from) -> Result<Self, Self::Error> {
$func(AsRef::<str>::as_ref(s)).map_err(|source| <$error>::new(s, source))
}
}
}
}
#[macro_export]
macro_rules! impl_parse {
($type:ty, $descr:expr, $func:expr, $vis:vis $error:ident, $error_source:ty $(, $error_derive:path)*) => {
$crate::parse_error_type!($vis $error, $error_source, $descr $(, $error_derive)*);
impl core::str::FromStr for $type {
type Err = $error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
$func(s).map_err(|source| <$error>::new(s, source))
}
}
impl_try_from_stringly!(&str);
#[cfg(feature = "alloc")]
impl_try_from_stringly!(alloc::string::String, $type, $error, $func);
#[cfg(feature = "alloc")]
impl_try_from_stringly!(alloc::borrow::Cow<'_, str>, $type, $error, $func);
#[cfg(feature = "alloc")]
impl_try_from_stringly!(alloc::boxed::Box<str>, $type, $error, $func);
}
}
#[macro_export]
macro_rules! impl_parse_and_serde {
($type:ty, $descr:expr, $func:expr, $error:ident, $error_source:ty $(, $error_derive:path)*) => {
impl_parse!($type, $descr, $func, $error, $error_source $(, $error_derive)*);
#[cfg(feature = "serde")]
impl<'de> $crate::serde::Deserialize<'de> for $type {
fn deserialize<D>(deserializer: D) -> Result<$name, D::Error>
where
D: $crate::serde::de::Deserializer<'de>,
{
use core::fmt::{self, Formatter};
use core::str::FromStr;
struct Visitor;
impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
type Value = $name;
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
f.write_str($descr)
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: $crate::serde::de::Error,
{
s.parse().map_err(|error| {
$crate::serde::IntoDeError::try_into_de_error(error)
.unwrap_or_else(|_| E::invalid_value(Unexpected::Str(s), &self))
})
}
}
deserializer.deserialize_str(Visitor)
}
}
#[cfg(feature = "serde")]
impl $crate::serde::Serialize for $name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: $crate::serde::Serializer,
{
serializer.collect_str(&self)
}
}
}
}