macro_rules! impl_bounded_number {
(@default $ty:ty, $default:expr, $doc:literal) => {
impl $ty {
#[doc = $doc]
pub const DEFAULT: Self = match Self::new($default) {
Ok(value) => value,
Err(_) => panic!(concat!(
"the default of ",
stringify!($ty),
" must be in range"
)),
};
}
impl ::std::default::Default for $ty {
fn default() -> Self {
Self::DEFAULT
}
}
};
(@convert [$($gen:tt)*] $ty:ty, $prim:ty, $err:ty, $into:expr) => {
impl<$($gen)*> ::std::convert::TryFrom<$prim> for $ty {
type Error = $err;
fn try_from(value: $prim) -> ::std::result::Result<Self, Self::Error> {
Self::new(value)
}
}
impl<$($gen)*> ::std::convert::From<$ty> for $prim {
fn from(value: $ty) -> Self {
($into)(value)
}
}
};
($ty:ty, $prim:ty, infallible, default = $default:expr, $doc:literal, into = $into:expr) => {
impl $ty {
#[doc = $doc]
pub const DEFAULT: Self = Self::new($default);
}
impl ::std::default::Default for $ty {
fn default() -> Self {
Self::DEFAULT
}
}
impl ::std::convert::From<$prim> for $ty {
fn from(value: $prim) -> Self {
Self::new(value)
}
}
impl ::std::convert::From<$ty> for $prim {
fn from(value: $ty) -> Self {
($into)(value)
}
}
};
($ty:ty, $prim:ty, $err:ty, default = $default:expr, $doc:literal, into = $into:expr) => {
impl_bounded_number!(@default $ty, $default, $doc);
impl_bounded_number!(@convert [] $ty, $prim, $err, $into);
};
}
pub(super) use impl_bounded_number;