#![no_std]
#[cfg(feature = "serde")]
#[doc(hidden)]
#[macro_export]
macro_rules! add_deserialize {
($type:ident, $parent:ty) => {
impl<'de> serde::Deserialize<'de> for $type {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
use core::convert::TryInto as _;
use serde::de::Error as _;
<$parent as serde::Deserialize>::deserialize(deserializer)?
.try_into()
.map_err(D::Error::custom)
}
}
};
}
#[cfg(not(feature = "serde"))]
#[doc(hidden)]
#[macro_export]
macro_rules! add_deserialize {
($type:ident, $parent:ty) => {};
}
#[doc(hidden)]
#[macro_export]
macro_rules! add_try_from {
($type:ident, $parent:ty, $predicate:expr, $error_type:ty, $error:expr) => {
impl core::convert::TryFrom<$parent> for $type {
type Error = $error_type;
fn try_from(val: $parent) -> Result<Self, $error_type> {
if $predicate(&val) {
Ok($type(val))
} else {
Err($error(&val).into())
}
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! add_deref {
($type:ident, $parent:ty) => {
impl core::ops::Deref for $type {
type Target = $parent;
fn deref(&self) -> &$parent {
&self.0
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! uniform_validated_newtype {
(
$( #[$attr:meta] )*
$parent:ty => $vis:vis $type:ident
$(
if $predicate:expr;
else $error:expr => $error_type:ty
)?
) => {
#[allow(unused_attributes)]
$( #[$attr] )*
$vis struct $type($parent);
$(
$crate::add_try_from!($type, $parent, $predicate, $error_type, $error);
)?
$crate::add_deserialize!($type, $parent);
$crate::add_deref!($type, $parent);
}
}
#[macro_export]
macro_rules! validated_newtype {
(
$( #[$attr:meta] )*
$parent:ty => $vis:vis $type:ident
$(
if $predicate:expr;
else $error:expr => $error_type:ty
)?
) => {
$crate::uniform_validated_newtype! {
$( #[$attr] )*
$parent => $vis $type
$(
if $predicate;
else $error => $error_type
)?
}
};
(
$( #[$attr:meta] )*
$parent:ty => $vis:vis $type:ident
if $predicate:expr;
error $message:literal
) => {
$crate::uniform_validated_newtype! {
$( #[$attr] )*
$parent => $vis $type
if $predicate;
else |_| $message => &'static str
}
};
}