use crate::Error;
macro_rules! for_each_index {
($mac:ident) => {
$mac! {
Slot(pub(crate) u16);
Func(pub(crate) u32);
FuncType(pub(crate) u32);
InternalFunc(pub(crate) u32);
Global(pub(crate) u32);
Memory(pub(crate) u16);
Table(pub(crate) u32);
Data(pub(crate) u32);
Elem(pub(crate) u32);
}
};
}
impl Memory {
pub fn is_default(&self) -> bool {
self.0 == 0
}
}
macro_rules! define_index {
(
$(
$( #[$docs:meta] )*
$name:ident($vis:vis $ty:ty)
);* $(;)?
) => {
$(
$( #[$docs] )*
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct $name($vis $ty);
impl From<$name> for $ty {
fn from(value: $name) -> $ty {
value.0
}
}
impl From<$ty> for $name {
fn from(value: $ty) -> Self {
Self(value)
}
}
)*
};
}
for_each_index!(define_index);
impl From<Memory> for u32 {
fn from(value: Memory) -> Self {
u32::from(value.0)
}
}
impl TryFrom<u32> for Memory {
type Error = Error;
fn try_from(index: u32) -> Result<Self, Self::Error> {
u16::try_from(index)
.map_err(|_| Error::MemoryIndexOutOfBounds)
.map(Self::from)
}
}
impl TryFrom<u32> for Slot {
type Error = Error;
fn try_from(local_index: u32) -> Result<Self, Self::Error> {
u16::try_from(local_index)
.map_err(|_| Error::StackSlotOutOfBounds)
.map(Self::from)
}
}
impl Slot {
pub fn next_n(self, n: u16) -> Self {
Self(self.0.wrapping_add(n))
}
pub fn prev_n(self, n: u16) -> Self {
Self(self.0.wrapping_sub(n))
}
pub fn next(self) -> Self {
self.next_n(1)
}
pub fn prev(self) -> Self {
self.prev_n(1)
}
}