use crate::{
Alias, BinaryReader, ComponentAlias, ComponentImport, ComponentTypeRef, FuncType, Import,
Result, SectionIteratorLimited, SectionReader, SectionWithLimitedItems, Type, TypeRef,
};
use std::ops::Range;
#[derive(Debug, Clone)]
pub enum CoreType<'a> {
Func(FuncType),
Module(Box<[ModuleTypeDeclaration<'a>]>),
}
#[derive(Debug, Clone)]
pub enum ModuleTypeDeclaration<'a> {
Type(Type),
Export {
name: &'a str,
ty: TypeRef,
},
Alias(Alias<'a>),
Import(Import<'a>),
}
#[derive(Clone)]
pub struct CoreTypeSectionReader<'a> {
reader: BinaryReader<'a>,
count: u32,
}
impl<'a> CoreTypeSectionReader<'a> {
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
let mut reader = BinaryReader::new_with_offset(data, offset);
let count = reader.read_var_u32()?;
Ok(Self { reader, count })
}
pub fn original_position(&self) -> usize {
self.reader.original_position()
}
pub fn get_count(&self) -> u32 {
self.count
}
pub fn read(&mut self) -> Result<CoreType<'a>> {
self.reader.read_core_type()
}
}
impl<'a> SectionReader for CoreTypeSectionReader<'a> {
type Item = CoreType<'a>;
fn read(&mut self) -> Result<Self::Item> {
Self::read(self)
}
fn eof(&self) -> bool {
self.reader.eof()
}
fn original_position(&self) -> usize {
Self::original_position(self)
}
fn range(&self) -> Range<usize> {
self.reader.range()
}
}
impl<'a> SectionWithLimitedItems for CoreTypeSectionReader<'a> {
fn get_count(&self) -> u32 {
Self::get_count(self)
}
}
impl<'a> IntoIterator for CoreTypeSectionReader<'a> {
type Item = Result<CoreType<'a>>;
type IntoIter = SectionIteratorLimited<Self>;
fn into_iter(self) -> Self::IntoIter {
SectionIteratorLimited::new(self)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ComponentValType {
Primitive(PrimitiveValType),
Type(u32),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PrimitiveValType {
Bool,
S8,
U8,
S16,
U16,
S32,
U32,
S64,
U64,
Float32,
Float64,
Char,
String,
}
impl PrimitiveValType {
pub(crate) fn requires_realloc(&self) -> bool {
matches!(self, Self::String)
}
pub fn is_subtype_of(a: Self, b: Self) -> bool {
a == b
|| matches!(
(a, b),
(Self::S8, Self::S16)
| (Self::S8, Self::S32)
| (Self::S8, Self::S64)
| (Self::U8, Self::U16)
| (Self::U8, Self::U32)
| (Self::U8, Self::U64)
| (Self::U8, Self::S16)
| (Self::U8, Self::S32)
| (Self::U8, Self::S64)
| (Self::S16, Self::S32)
| (Self::S16, Self::S64)
| (Self::U16, Self::U32)
| (Self::U16, Self::U64)
| (Self::U16, Self::S32)
| (Self::U16, Self::S64)
| (Self::S32, Self::S64)
| (Self::U32, Self::U64)
| (Self::U32, Self::S64)
| (Self::Float32, Self::Float64)
)
}
}
#[derive(Debug, Clone)]
pub enum ComponentType<'a> {
Defined(ComponentDefinedType<'a>),
Func(ComponentFuncType<'a>),
Component(Box<[ComponentTypeDeclaration<'a>]>),
Instance(Box<[InstanceTypeDeclaration<'a>]>),
}
#[derive(Debug, Clone)]
pub enum ComponentTypeDeclaration<'a> {
CoreType(CoreType<'a>),
Type(ComponentType<'a>),
Alias(ComponentAlias<'a>),
Export {
name: &'a str,
ty: ComponentTypeRef,
},
Import(ComponentImport<'a>),
}
#[derive(Debug, Clone)]
pub enum InstanceTypeDeclaration<'a> {
CoreType(CoreType<'a>),
Type(ComponentType<'a>),
Alias(ComponentAlias<'a>),
Export {
name: &'a str,
ty: ComponentTypeRef,
},
}
#[derive(Debug, Clone)]
pub enum TypeVec<'a> {
Unnamed(ComponentValType),
Named(Box<[(&'a str, ComponentValType)]>),
}
impl TypeVec<'_> {
pub fn len(&self) -> usize {
match self {
Self::Unnamed(_) => 1,
Self::Named(vec) => vec.len(),
}
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn iter(&self) -> impl Iterator<Item = (Option<&str>, &ComponentValType)> {
enum Either<L, R> {
Left(L),
Right(R),
}
impl<L, R> Iterator for Either<L, R>
where
L: Iterator,
R: Iterator<Item = L::Item>,
{
type Item = L::Item;
fn next(&mut self) -> Option<Self::Item> {
match self {
Either::Left(l) => l.next(),
Either::Right(r) => r.next(),
}
}
}
match self {
Self::Unnamed(ty) => Either::Left(std::iter::once(ty).map(|ty| (None, ty))),
Self::Named(vec) => Either::Right(vec.iter().map(|(n, ty)| (Some(*n), ty))),
}
}
}
#[derive(Debug, Clone)]
pub struct ComponentFuncType<'a> {
pub params: TypeVec<'a>,
pub results: TypeVec<'a>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VariantCase<'a> {
pub name: &'a str,
pub ty: Option<ComponentValType>,
pub refines: Option<u32>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ComponentDefinedType<'a> {
Primitive(PrimitiveValType),
Record(Box<[(&'a str, ComponentValType)]>),
Variant(Box<[VariantCase<'a>]>),
List(ComponentValType),
Tuple(Box<[ComponentValType]>),
Flags(Box<[&'a str]>),
Enum(Box<[&'a str]>),
Union(Box<[ComponentValType]>),
Option(ComponentValType),
Result {
ok: Option<ComponentValType>,
err: Option<ComponentValType>,
},
}
#[derive(Clone)]
pub struct ComponentTypeSectionReader<'a> {
reader: BinaryReader<'a>,
count: u32,
}
impl<'a> ComponentTypeSectionReader<'a> {
pub fn new(data: &'a [u8], offset: usize) -> Result<Self> {
let mut reader = BinaryReader::new_with_offset(data, offset);
let count = reader.read_var_u32()?;
Ok(Self { reader, count })
}
pub fn original_position(&self) -> usize {
self.reader.original_position()
}
pub fn get_count(&self) -> u32 {
self.count
}
pub fn read(&mut self) -> Result<ComponentType<'a>> {
self.reader.read_component_type()
}
}
impl<'a> SectionReader for ComponentTypeSectionReader<'a> {
type Item = ComponentType<'a>;
fn read(&mut self) -> Result<Self::Item> {
Self::read(self)
}
fn eof(&self) -> bool {
self.reader.eof()
}
fn original_position(&self) -> usize {
Self::original_position(self)
}
fn range(&self) -> Range<usize> {
self.reader.range()
}
}
impl<'a> SectionWithLimitedItems for ComponentTypeSectionReader<'a> {
fn get_count(&self) -> u32 {
Self::get_count(self)
}
}
impl<'a> IntoIterator for ComponentTypeSectionReader<'a> {
type Item = Result<ComponentType<'a>>;
type IntoIter = SectionIteratorLimited<Self>;
fn into_iter(self) -> Self::IntoIter {
SectionIteratorLimited::new(self)
}
}