use core::slice;
use wasmi::FuncType;
#[derive(Debug, Default)]
pub struct ModuleExports {
funcs: StringSequence,
func_types: Vec<FuncType>,
globals: StringSequence,
memories: StringSequence,
tables: StringSequence,
}
impl ModuleExports {
pub(crate) fn push_func(&mut self, name: &str, ty: FuncType) {
self.funcs.push(name);
self.func_types.push(ty);
}
pub(crate) fn push_global(&mut self, name: &str) {
self.globals.push(name);
}
pub(crate) fn push_memory(&mut self, name: &str) {
self.memories.push(name);
}
pub(crate) fn push_table(&mut self, name: &str) {
self.tables.push(name);
}
pub fn funcs(&self) -> ExportedFuncsIter<'_> {
ExportedFuncsIter {
names: self.funcs.iter(),
types: self.func_types.iter(),
}
}
pub fn globals(&self) -> StringSequenceIter<'_> {
self.globals.iter()
}
pub fn memories(&self) -> StringSequenceIter<'_> {
self.memories.iter()
}
pub fn tables(&self) -> StringSequenceIter<'_> {
self.tables.iter()
}
}
#[derive(Debug)]
pub struct ExportedFuncsIter<'a> {
names: StringSequenceIter<'a>,
types: slice::Iter<'a, FuncType>,
}
impl<'a> Iterator for ExportedFuncsIter<'a> {
type Item = (&'a str, &'a FuncType);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let name = self.names.next()?;
let ty = self.types.next()?;
Some((name, ty))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.names.size_hint()
}
}
#[derive(Debug, Default)]
pub struct StringSequence {
strings: Vec<Box<str>>,
}
impl StringSequence {
pub fn push(&mut self, s: &str) {
self.strings.push(Box::from(s));
}
pub fn iter(&self) -> StringSequenceIter<'_> {
StringSequenceIter {
iter: self.strings.iter(),
}
}
}
#[derive(Debug)]
pub struct StringSequenceIter<'a> {
iter: slice::Iter<'a, Box<str>>,
}
impl<'a> Iterator for StringSequenceIter<'a> {
type Item = &'a str;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|s| &**s)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl ExactSizeIterator for StringSequenceIter<'_> {}