use crate::{
AsContext,
Func,
FuncType,
Global,
GlobalType,
Memory,
MemoryType,
Table,
TableType,
collections::map::Iter as MapIter,
};
use alloc::boxed::Box;
use core::iter::FusedIterator;
#[derive(Debug, Copy, Clone)]
pub enum Extern {
Global(Global),
Table(Table),
Memory(Memory),
Func(Func),
}
impl From<Global> for Extern {
fn from(global: Global) -> Self {
Self::Global(global)
}
}
impl From<Table> for Extern {
fn from(table: Table) -> Self {
Self::Table(table)
}
}
impl From<Memory> for Extern {
fn from(memory: Memory) -> Self {
Self::Memory(memory)
}
}
impl From<Func> for Extern {
fn from(func: Func) -> Self {
Self::Func(func)
}
}
impl Extern {
pub fn into_global(self) -> Option<Global> {
if let Self::Global(global) = self {
return Some(global);
}
None
}
pub fn into_table(self) -> Option<Table> {
if let Self::Table(table) = self {
return Some(table);
}
None
}
pub fn into_memory(self) -> Option<Memory> {
if let Self::Memory(memory) = self {
return Some(memory);
}
None
}
pub fn into_func(self) -> Option<Func> {
if let Self::Func(func) = self {
return Some(func);
}
None
}
pub fn ty(&self, ctx: impl AsContext) -> ExternType {
match self {
Extern::Global(global) => global.ty(ctx).into(),
Extern::Table(table) => table.ty(ctx).into(),
Extern::Memory(memory) => memory.ty(ctx).into(),
Extern::Func(func) => func.ty(ctx).into(),
}
}
}
#[derive(Debug, Clone)]
pub enum ExternType {
Global(GlobalType),
Table(TableType),
Memory(MemoryType),
Func(FuncType),
}
impl From<GlobalType> for ExternType {
fn from(global: GlobalType) -> Self {
Self::Global(global)
}
}
impl From<TableType> for ExternType {
fn from(table: TableType) -> Self {
Self::Table(table)
}
}
impl From<MemoryType> for ExternType {
fn from(memory: MemoryType) -> Self {
Self::Memory(memory)
}
}
impl From<FuncType> for ExternType {
fn from(func: FuncType) -> Self {
Self::Func(func)
}
}
impl ExternType {
pub fn global(&self) -> Option<&GlobalType> {
match self {
Self::Global(ty) => Some(ty),
_ => None,
}
}
pub fn table(&self) -> Option<&TableType> {
match self {
Self::Table(ty) => Some(ty),
_ => None,
}
}
pub fn memory(&self) -> Option<&MemoryType> {
match self {
Self::Memory(ty) => Some(ty),
_ => None,
}
}
pub fn func(&self) -> Option<&FuncType> {
match self {
Self::Func(ty) => Some(ty),
_ => None,
}
}
}
#[derive(Debug, Clone)]
pub struct Export<'instance> {
name: &'instance str,
definition: Extern,
}
impl<'instance> Export<'instance> {
pub(crate) fn new(name: &'instance str, definition: Extern) -> Export<'instance> {
Self { name, definition }
}
pub fn name(&self) -> &'instance str {
self.name
}
pub fn ty(&self, ctx: impl AsContext) -> ExternType {
self.definition.ty(ctx)
}
pub fn into_extern(self) -> Extern {
self.definition
}
pub fn into_func(self) -> Option<Func> {
self.definition.into_func()
}
pub fn into_table(self) -> Option<Table> {
self.definition.into_table()
}
pub fn into_memory(self) -> Option<Memory> {
self.definition.into_memory()
}
pub fn into_global(self) -> Option<Global> {
self.definition.into_global()
}
}
#[derive(Debug)]
pub struct ExportsIter<'instance> {
iter: MapIter<'instance, Box<str>, Extern>,
}
impl<'instance> ExportsIter<'instance> {
pub(super) fn new(iter: MapIter<'instance, Box<str>, Extern>) -> Self {
Self { iter }
}
#[allow(clippy::borrowed_box)]
fn convert_item((name, export): (&'instance Box<str>, &'instance Extern)) -> Export<'instance> {
Export::new(name, *export)
}
}
impl<'instance> Iterator for ExportsIter<'instance> {
type Item = Export<'instance>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(Self::convert_item)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl ExactSizeIterator for ExportsIter<'_> {}
impl FusedIterator for ExportsIter<'_> {}