use crate::error::{Error, ErrorCode};
macro_rules! fromtlv_for {
($($t:ident)*) => {
$(
impl<'a> $crate::tlv::FromTLV<'a> for $t {
fn from_tlv(element: &$crate::tlv::TLVElement<'a>) -> Result<Self, Error> {
element.$t()
}
}
)*
};
}
macro_rules! fromtlv_for_num {
($($t:ident)*) => {
$(
impl<'a> $crate::tlv::FromTLV<'a> for $t {
fn from_tlv(element: &$crate::tlv::TLVElement<'a>) -> Result<Self, Error> {
element.$t()
}
fn nullable_from_tlv(element: &$crate::tlv::TLVElement<'a>) -> Result<Self, Error> {
let value = element.$t()?;
let in_range = if $t::MIN == 0 {
value != $t::MAX
} else {
value != $t::MIN
};
if in_range {
Ok(value)
} else {
Err(ErrorCode::ConstraintError.into())
}
}
}
)*
};
}
macro_rules! fromtlv_for_nonzero {
($($t:ident:$n:ty)*) => {
$(
impl<'a> $crate::tlv::FromTLV<'a> for $n {
fn from_tlv(element: &$crate::tlv::TLVElement<'a>) -> Result<Self, Error> {
<$n>::new(element.$t()?).ok_or_else(|| ErrorCode::Invalid.into())
}
fn nullable_from_tlv(element: &$crate::tlv::TLVElement<'a>) -> Result<Self, Error> {
let value = element.$t()?;
let in_range = if $t::MIN == 0 {
value != $t::MAX
} else {
value != $t::MIN
};
if in_range {
<$n>::new(value).ok_or_else(|| ErrorCode::Invalid.into())
} else {
Err(ErrorCode::ConstraintError.into())
}
}
}
)*
};
}
macro_rules! totlv_for {
($($t:ident)*) => {
$(
impl $crate::tlv::ToTLV for $t {
fn to_tlv<W: $crate::tlv::TLVWrite>(&self, tag: &$crate::tlv::TLVTag, mut tw: W) -> Result<(), Error> {
tw.$t(tag, *self)
}
fn tlv_iter(&self, tag: $crate::tlv::TLVTag) -> impl Iterator<Item = Result<$crate::tlv::TLV<'_>, Error>> {
$crate::tlv::TLV::$t(tag, *self).into_tlv_iter()
}
}
)*
};
}
macro_rules! totlv_for_num {
($($t:ident)*) => {
$(
impl $crate::tlv::ToTLV for $t {
fn to_tlv<W: $crate::tlv::TLVWrite>(&self, tag: &$crate::tlv::TLVTag, mut tw: W) -> Result<(), Error> {
tw.$t(tag, *self)
}
fn tlv_iter(&self, tag: $crate::tlv::TLVTag) -> impl Iterator<Item = Result<$crate::tlv::TLV<'_>, Error>> {
$crate::tlv::TLV::$t(tag, *self).into_tlv_iter()
}
fn nullable_to_tlv<W: $crate::tlv::TLVWrite>(&self, tag: &$crate::tlv::TLVTag, mut tw: W) -> Result<(), Error> {
let in_range = if $t::MIN == 0 {
*self != $t::MAX
} else {
*self != $t::MIN
};
if in_range {
tw.$t(tag, *self)
} else {
Err(ErrorCode::ConstraintError.into())
}
}
fn nullable_tlv_iter(&self, tag: $crate::tlv::TLVTag) -> impl Iterator<Item = Result<$crate::tlv::TLV<'_>, Error>> {
let in_range = if $t::MIN == 0 {
*self != $t::MAX
} else {
*self != $t::MIN
};
if in_range {
$crate::tlv::EitherIter::First($crate::tlv::TLV::$t(tag, *self).into_tlv_iter())
} else {
$crate::tlv::EitherIter::Second(core::iter::once(Err(ErrorCode::ConstraintError.into())))
}
}
}
)*
};
}
macro_rules! totlv_for_nonzero {
($($t:ident:$n:ty)*) => {
$(
impl $crate::tlv::ToTLV for $n {
fn to_tlv<W: $crate::tlv::TLVWrite>(&self, tag: &$crate::tlv::TLVTag, mut tw: W) -> Result<(), Error> {
tw.$t(tag, self.get())
}
fn tlv_iter(&self, tag: $crate::tlv::TLVTag) -> impl Iterator<Item = Result<$crate::tlv::TLV<'_>, Error>> {
$crate::tlv::TLV::$t(tag, self.get()).into_tlv_iter()
}
fn nullable_to_tlv<W: $crate::tlv::TLVWrite>(&self, tag: &$crate::tlv::TLVTag, mut tw: W) -> Result<(), Error> {
let in_range = if $t::MIN == 0 {
self.get() != $t::MAX
} else {
self.get() != $t::MIN
};
if in_range {
tw.$t(tag, self.get())
} else {
Err(ErrorCode::ConstraintError.into())
}
}
fn nullable_tlv_iter(&self, tag: $crate::tlv::TLVTag) -> impl Iterator<Item = Result<$crate::tlv::TLV<'_>, Error>> {
let in_range = if $t::MIN == 0 {
self.get() != $t::MAX
} else {
self.get() != $t::MIN
};
if in_range {
$crate::tlv::EitherIter::First($crate::tlv::TLV::$t(tag, self.get()).into_tlv_iter())
} else {
$crate::tlv::EitherIter::Second(core::iter::once(Err(ErrorCode::ConstraintError.into())))
}
}
}
)*
};
}
fromtlv_for!(f32 f64 bool);
fromtlv_for_num!(i8 u8 i16 u16 i32 u32 i64 u64);
fromtlv_for_nonzero!(i8:core::num::NonZeroI8 u8:core::num::NonZeroU8 i16:core::num::NonZeroI16 u16:core::num::NonZeroU16 i32:core::num::NonZeroI32 u32:core::num::NonZeroU32 i64:core::num::NonZeroI64 u64:core::num::NonZeroU64);
totlv_for!(f32 f64 bool);
totlv_for_num!(i8 u8 i16 u16 i32 u32 i64 u64);
totlv_for_nonzero!(i8:core::num::NonZeroI8 u8:core::num::NonZeroU8 i16:core::num::NonZeroI16 u16:core::num::NonZeroU16 i32:core::num::NonZeroI32 u32:core::num::NonZeroU32 i64:core::num::NonZeroI64 u64:core::num::NonZeroU64);