#[macro_export]
macro_rules! u8_to_vec_of {
($a:expr, $b:ty) => {
$a.chunks_exact(std::mem::size_of::<$b>())
.map(TryInto::try_into)
.map(Result::unwrap)
.map(<$b>::from_le_bytes)
.collect()
};
}
#[macro_export]
macro_rules! u8_to_vec_of_bool {
($a:expr) => {
$a.iter().map(|x| *x > 0).collect::<Vec<bool>>()
};
}
#[macro_export]
macro_rules! write_tag_value_array {
($v:ident , $len_t:expr, $val_t: ty, $slice_name: ident, $writer:expr) => {
match $len_t {
RadIntId::U8 => {
let l: u8 = $v.len() as u8;
$writer
.write_all(&l.to_le_bytes())
.context("couldn't write array length as u8")?;
}
RadIntId::U16 => {
let l: u16 = $v.len() as u16;
$writer
.write_all(&l.to_le_bytes())
.context("couldn't write array length as u16")?;
}
RadIntId::U32 => {
let l: u32 = $v.len() as u32;
$writer
.write_all(&l.to_le_bytes())
.context("couldn't write array length as u32")?;
}
RadIntId::U64 => {
let l: u64 = $v.len() as u64;
$writer
.write_all(&l.to_le_bytes())
.context("couldn't write array length as u64")?;
}
RadIntId::U128 => {
let l: u128 = $v.len() as u128;
$writer
.write_all(&l.to_le_bytes())
.context("couldn't write array length as u128")?;
}
_ => {
anyhow::bail!("signed length values are unsupported in tag value arrays")
}
}
let $slice_name: &[u8] = bytemuck::try_cast_slice(&$v)
.or_else(|_e| Err(anyhow::anyhow!("could't convert array contents to &[u8]")))
.context("array conversion failed")?;
$writer
.write_all($slice_name)
.context("couldn't write values of the array")?;
};
}
#[macro_export]
macro_rules! tag_value_try_into_int {
($b:ty) => {
impl std::convert::TryInto<$b> for &libradicl::rad_types::TagValue {
type Error = anyhow::Error;
fn try_into(self) -> std::result::Result<$b, Self::Error> {
match *self {
TagValue::U8(x) => Ok(x as $b),
TagValue::U16(x) => Ok(x as $b),
TagValue::U32(x) => {
if x as u64 > <$b>::MAX as u64 {
bail!("Cannot convert value {x} to u16; too large")
} else {
Ok(x as $b)
}
}
TagValue::U64(x) => {
if x as u64 > <$b>::MAX as u64 {
bail!("Cannot convert value {x} to {}; too large", stringify!($b))
} else {
Ok(x as $b)
}
}
TagValue::U128(x) => {
if x as u128 > <$b>::MAX as u128 {
bail!("Cannot convert value {x} to {}; too large", stringify!($b))
} else {
Ok(x as $b)
}
}
TagValue::I8(x) => Ok(x as $b),
TagValue::I16(x) => Ok(x as $b),
TagValue::I32(x) => {
if x as i64 > <$b>::MAX as i64 {
bail!("Cannot convert value {x} to i16; too large")
} else if (x as i64) < <$b>::MIN as i64 {
bail!("Cannot convert value {x} to i16; too small")
} else {
Ok(x as $b)
}
}
TagValue::I64(x) => {
if x as i64 > <$b>::MAX as i64 {
bail!("Cannot convert value {x} to {}; too large", stringify!($b))
} else if (x as i64) < <$b>::MIN as i64 {
bail!("Cannot convert value {x} to i32; too small")
} else {
Ok(x as $b)
}
}
TagValue::I128(x) => {
if x as i128 > <$b>::MAX as i128 {
bail!("Cannot convert value {x} to {}; too large", stringify!($b))
} else if (x as i128) < <$b>::MIN as i128 {
bail!("Cannot convert value {x} to {}; too small", stringify!($b))
} else {
Ok(x as $b)
}
}
_ => {
bail!("cannot convert non-int TagValue to {}", stringify!($b))
}
}
}
}
};
}
#[macro_export]
macro_rules! as_u64 {
("NewU128") => {
impl std::convert::From<$from_type> for u64 {
#[inline(always)]
fn from(x: $from_type) -> Self {
panic!("cannot convert u128 into u64");
}
}
};
($from_type: ty) => {
impl std::convert::From<$from_type> for u64 {
#[inline(always)]
fn from(x: $from_type) -> Self {
x.0 as u64
}
}
};
}
#[macro_export]
macro_rules! as_i64 {
("NewI128") => {
impl std::convert::From<$from_type> for i64 {
#[inline(always)]
fn from(x: $from_type) -> Self {
panic!("cannot convert i128 into i64");
}
}
};
($from_type: ty) => {
impl std::convert::From<$from_type> for i64 {
#[inline(always)]
fn from(x: $from_type) -> Self {
x.0 as i64
}
}
};
}
#[macro_export]
macro_rules! as_u128 {
($from_type: ty) => {
impl std::convert::From<$from_type> for u128 {
#[inline(always)]
fn from(x: $from_type) -> Self {
x.0 as u128
}
}
};
}
#[macro_export]
macro_rules! as_i128 {
($from_type: ty) => {
impl std::convert::From<$from_type> for i128 {
#[inline(always)]
fn from(x: $from_type) -> Self {
x.0 as i128
}
}
};
}
#[macro_export]
macro_rules! try_as_u64 {
("NewU128") => {
impl std::convert::TryFrom<TryWrapper<$from_type>> for u64 {
type Error = &'static str;
#[inline(always)]
fn try_from(x: TryWrapper<$from_type>) -> Result<Self, Self::Error> {
Err("Cannot convert u128 into u64")
}
}
};
($from_type: ty) => {
impl std::convert::TryFrom<TryWrapper<$from_type>> for u64 {
type Error = &'static str;
#[inline(always)]
fn try_from(x: TryWrapper<$from_type>) -> Result<Self, Self::Error> {
Ok(x.0.0 as u64)
}
}
};
}
#[macro_export]
macro_rules! try_as_i64 {
("NewI128") => {
impl std::convert::TryFrom<TryWrapper<$from_type>> for i64 {
type Error = &'static str;
#[inline(always)]
fn try_from(x: TryWrapper<$from_type>) -> Result<Self, Self::Error> {
Err("Cannot convert i128 into i64")
}
}
};
($from_type: ty) => {
impl std::convert::TryFrom<TryWrapper<$from_type>> for i64 {
type Error = &'static str;
#[inline(always)]
fn try_from(x: TryWrapper<$from_type>) -> Result<Self, Self::Error> {
Ok(x.0.0 as i64)
}
}
};
}
#[macro_export]
macro_rules! try_as_u128 {
($from_type: ty) => {
impl std::convert::TryFrom<TryWrapper<$from_type>> for u128 {
type Error = &'static str;
#[inline(always)]
fn try_from(x: TryWrapper<$from_type>) -> Result<Self, Self::Error> {
Ok(x.0.0 as u128)
}
}
};
}
#[macro_export]
macro_rules! try_as_i128 {
($from_type: ty) => {
impl std::convert::TryFrom<TryWrapper<$from_type>> for i128 {
type Error = &'static str;
#[inline(always)]
fn try_from(x: TryWrapper<$from_type>) -> Result<Self, Self::Error> {
Ok(x.0.0 as i128)
}
}
};
}