use crate::{errors::ModuleError, GlobalType, MemoryType, TableType};
use alloc::boxed::Box;
use core::fmt::{self, Display};
use wasmparser::TypeRef;
#[derive(Debug)]
pub struct Import {
name: ImportName,
kind: ExternTypeIdx,
}
#[derive(Debug, Clone)]
pub struct ImportName {
module: Box<str>,
field: Box<str>,
}
impl Display for ImportName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let module_name = &*self.module;
let field_name = &*self.field;
write!(f, "{module_name}::{field_name}")
}
}
impl ImportName {
pub fn new(module: &str, field: &str) -> Self {
Self {
module: module.into(),
field: field.into(),
}
}
pub fn module(&self) -> &str {
&self.module
}
pub fn name(&self) -> &str {
&self.field
}
}
impl TryFrom<wasmparser::Import<'_>> for Import {
type Error = ModuleError;
fn try_from(import: wasmparser::Import) -> Result<Self, Self::Error> {
let kind = match import.ty {
TypeRef::Func(func_type) => Ok(ExternTypeIdx::Func(FuncTypeIdx(func_type))),
TypeRef::Table(table_type) => table_type.try_into().map(ExternTypeIdx::Table),
TypeRef::Memory(memory_type) => memory_type.try_into().map(ExternTypeIdx::Memory),
TypeRef::Global(global_type) => global_type.try_into().map(ExternTypeIdx::Global),
TypeRef::Tag(tag) => panic!(
"wasmi does not support the `exception-handling` Wasm proposal but found: {tag:?}"
),
}?;
Ok(Self::new(import.module, import.name, kind))
}
}
impl Import {
pub fn new(module: &str, field: &str, kind: ExternTypeIdx) -> Self {
Self {
name: ImportName::new(module, field),
kind,
}
}
pub fn into_name_and_type(self) -> (ImportName, ExternTypeIdx) {
(self.name, self.kind)
}
}
#[derive(Debug)]
pub enum ExternTypeIdx {
Func(FuncTypeIdx),
Table(TableType),
Memory(MemoryType),
Global(GlobalType),
}
#[derive(Debug, Copy, Clone)]
pub struct FuncTypeIdx(pub(crate) u32);
impl FuncTypeIdx {
pub fn into_usize(self) -> usize {
self.0 as usize
}
}