use crate::{
encode_functype, encode_section, ComponentSection, ComponentSectionId, Encode, EntityType,
ValType,
};
#[derive(Debug, Clone, Default)]
pub struct ModuleType {
bytes: Vec<u8>,
num_added: u32,
types_added: u32,
}
impl ModuleType {
pub fn new() -> Self {
Self::default()
}
pub fn function<P, R>(&mut self, params: P, results: R) -> &mut Self
where
P: IntoIterator<Item = ValType>,
P::IntoIter: ExactSizeIterator,
R: IntoIterator<Item = ValType>,
R::IntoIter: ExactSizeIterator,
{
self.bytes.push(0x01);
encode_functype(&mut self.bytes, params, results);
self.num_added += 1;
self.types_added += 1;
self
}
pub fn import(&mut self, module: &str, name: &str, ty: EntityType) -> &mut Self {
self.bytes.push(0x02);
module.encode(&mut self.bytes);
name.encode(&mut self.bytes);
ty.encode(&mut self.bytes);
self.num_added += 1;
self
}
pub fn export(&mut self, name: &str, ty: EntityType) -> &mut Self {
self.bytes.push(0x07);
name.encode(&mut self.bytes);
ty.encode(&mut self.bytes);
self.num_added += 1;
self
}
pub fn type_count(&self) -> u32 {
self.types_added
}
}
impl Encode for ModuleType {
fn encode(&self, sink: &mut Vec<u8>) {
self.num_added.encode(sink);
sink.extend(&self.bytes);
}
}
#[derive(Debug, Clone, Default)]
pub struct ComponentType {
bytes: Vec<u8>,
num_added: u32,
types_added: u32,
}
impl ComponentType {
pub fn new() -> Self {
Self::default()
}
#[must_use = "the encoder must be used to encode the type"]
pub fn ty(&mut self) -> TypeEncoder {
self.bytes.push(0x01);
self.num_added += 1;
self.types_added += 1;
TypeEncoder(&mut self.bytes)
}
pub fn import(&mut self, name: &str, ty: u32) -> &mut Self {
self.bytes.push(0x02);
name.encode(&mut self.bytes);
ty.encode(&mut self.bytes);
self.num_added += 1;
self
}
pub fn export(&mut self, name: &str, ty: u32) -> &mut Self {
self.bytes.push(0x07);
name.encode(&mut self.bytes);
ty.encode(&mut self.bytes);
self.num_added += 1;
self
}
pub fn alias_outer_type(&mut self, count: u32, index: u32) -> &mut Self {
self.bytes.push(0x09);
self.bytes.push(0x02);
self.bytes.push(0x05);
count.encode(&mut self.bytes);
index.encode(&mut self.bytes);
self.num_added += 1;
self.types_added += 1;
self
}
pub fn type_count(&self) -> u32 {
self.types_added
}
}
impl Encode for ComponentType {
fn encode(&self, sink: &mut Vec<u8>) {
self.num_added.encode(sink);
sink.extend(&self.bytes);
}
}
#[derive(Debug, Clone, Default)]
pub struct InstanceType {
bytes: Vec<u8>,
num_added: u32,
types_added: u32,
}
impl InstanceType {
pub fn new() -> Self {
Self::default()
}
#[must_use = "the encoder must be used to encode the type"]
pub fn ty(&mut self) -> TypeEncoder {
self.bytes.push(0x01);
self.num_added += 1;
self.types_added += 1;
TypeEncoder(&mut self.bytes)
}
pub fn export(&mut self, name: &str, ty: u32) -> &mut Self {
self.bytes.push(0x07);
name.encode(&mut self.bytes);
ty.encode(&mut self.bytes);
self.num_added += 1;
self
}
pub fn alias_outer_type(&mut self, count: u32, index: u32) -> &mut Self {
self.bytes.push(0x09);
self.bytes.push(0x02);
self.bytes.push(0x05);
count.encode(&mut self.bytes);
index.encode(&mut self.bytes);
self.num_added += 1;
self.types_added += 1;
self
}
pub fn type_count(&self) -> u32 {
self.types_added
}
}
impl Encode for InstanceType {
fn encode(&self, sink: &mut Vec<u8>) {
self.num_added.encode(sink);
sink.extend(&self.bytes);
}
}
#[derive(Debug)]
pub struct TypeEncoder<'a>(&'a mut Vec<u8>);
impl<'a> TypeEncoder<'a> {
pub fn module(self, ty: &ModuleType) {
self.0.push(0x4f);
ty.encode(self.0);
}
pub fn component(self, ty: &ComponentType) {
self.0.push(0x4e);
ty.encode(self.0);
}
pub fn instance(self, ty: &InstanceType) {
self.0.push(0x4d);
ty.encode(self.0);
}
pub fn function<'b, P, T>(self, params: P, result: impl Into<InterfaceTypeRef>)
where
P: IntoIterator<Item = (Option<&'b str>, T)>,
P::IntoIter: ExactSizeIterator,
T: Into<InterfaceTypeRef>,
{
let params = params.into_iter();
self.0.push(0x4c);
params.len().encode(self.0);
for (name, ty) in params {
match name {
Some(name) => {
self.0.push(0x01);
name.encode(self.0);
}
None => self.0.push(0x00),
}
ty.into().encode(self.0);
}
result.into().encode(self.0);
}
pub fn value(self, ty: impl Into<InterfaceTypeRef>) {
self.0.push(0x4b);
ty.into().encode(self.0);
}
#[must_use = "the encoder must be used to encode the type"]
pub fn interface_type(self) -> InterfaceTypeEncoder<'a> {
InterfaceTypeEncoder(self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PrimitiveInterfaceType {
Unit,
Bool,
S8,
U8,
S16,
U16,
S32,
U32,
S64,
U64,
Float32,
Float64,
Char,
String,
}
impl Encode for PrimitiveInterfaceType {
fn encode(&self, sink: &mut Vec<u8>) {
sink.push(match self {
Self::Unit => 0x7f,
Self::Bool => 0x7e,
Self::S8 => 0x7d,
Self::U8 => 0x7c,
Self::S16 => 0x7b,
Self::U16 => 0x7a,
Self::S32 => 0x79,
Self::U32 => 0x78,
Self::S64 => 0x77,
Self::U64 => 0x76,
Self::Float32 => 0x75,
Self::Float64 => 0x74,
Self::Char => 0x73,
Self::String => 0x72,
});
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum InterfaceTypeRef {
Primitive(PrimitiveInterfaceType),
Type(u32),
}
impl Encode for InterfaceTypeRef {
fn encode(&self, sink: &mut Vec<u8>) {
match self {
Self::Primitive(ty) => ty.encode(sink),
Self::Type(index) => (*index as i64).encode(sink),
}
}
}
impl From<PrimitiveInterfaceType> for InterfaceTypeRef {
fn from(ty: PrimitiveInterfaceType) -> Self {
Self::Primitive(ty)
}
}
#[derive(Debug)]
pub struct InterfaceTypeEncoder<'a>(&'a mut Vec<u8>);
impl InterfaceTypeEncoder<'_> {
pub fn primitive(self, ty: PrimitiveInterfaceType) {
ty.encode(self.0);
}
pub fn record<'a, F, T>(self, fields: F)
where
F: IntoIterator<Item = (&'a str, T)>,
F::IntoIter: ExactSizeIterator,
T: Into<InterfaceTypeRef>,
{
let fields = fields.into_iter();
self.0.push(0x71);
fields.len().encode(self.0);
for (name, ty) in fields {
name.encode(self.0);
ty.into().encode(self.0);
}
}
pub fn variant<'a, C, T>(self, cases: C)
where
C: IntoIterator<Item = (&'a str, T, Option<u32>)>,
C::IntoIter: ExactSizeIterator,
T: Into<InterfaceTypeRef>,
{
let cases = cases.into_iter();
self.0.push(0x70);
cases.len().encode(self.0);
for (name, ty, default_to) in cases {
name.encode(self.0);
ty.into().encode(self.0);
if let Some(default) = default_to {
self.0.push(0x01);
default.encode(self.0);
} else {
self.0.push(0x00);
}
}
}
pub fn list(self, ty: impl Into<InterfaceTypeRef>) {
self.0.push(0x6f);
ty.into().encode(self.0);
}
pub fn tuple<I, T>(self, types: I)
where
I: IntoIterator<Item = T>,
I::IntoIter: ExactSizeIterator,
T: Into<InterfaceTypeRef>,
{
let types = types.into_iter();
self.0.push(0x6E);
types.len().encode(self.0);
for ty in types {
ty.into().encode(self.0);
}
}
pub fn flags<'a, I>(self, names: I)
where
I: IntoIterator<Item = &'a str>,
I::IntoIter: ExactSizeIterator,
{
let names = names.into_iter();
self.0.push(0x6D);
names.len().encode(self.0);
for name in names {
name.encode(self.0);
}
}
pub fn enum_type<'a, I>(self, tags: I)
where
I: IntoIterator<Item = &'a str>,
I::IntoIter: ExactSizeIterator,
{
let tags = tags.into_iter();
self.0.push(0x6C);
tags.len().encode(self.0);
for tag in tags {
tag.encode(self.0);
}
}
pub fn union<I, T>(self, types: I)
where
I: IntoIterator<Item = T>,
I::IntoIter: ExactSizeIterator,
T: Into<InterfaceTypeRef>,
{
let types = types.into_iter();
self.0.push(0x6B);
types.len().encode(self.0);
for ty in types {
ty.into().encode(self.0);
}
}
pub fn option(self, ty: impl Into<InterfaceTypeRef>) {
self.0.push(0x6A);
ty.into().encode(self.0);
}
pub fn expected(self, ok: impl Into<InterfaceTypeRef>, error: impl Into<InterfaceTypeRef>) {
self.0.push(0x69);
ok.into().encode(self.0);
error.into().encode(self.0);
}
}
#[derive(Clone, Debug, Default)]
pub struct ComponentTypeSection {
bytes: Vec<u8>,
num_added: u32,
}
impl ComponentTypeSection {
pub fn new() -> Self {
Self::default()
}
pub fn len(&self) -> u32 {
self.num_added
}
pub fn is_empty(&self) -> bool {
self.num_added == 0
}
#[must_use = "the encoder must be used to encode the type"]
pub fn ty(&mut self) -> TypeEncoder<'_> {
self.num_added += 1;
TypeEncoder(&mut self.bytes)
}
pub fn module(&mut self, ty: &ModuleType) -> &mut Self {
self.ty().module(ty);
self
}
pub fn component(&mut self, ty: &ComponentType) -> &mut Self {
self.ty().component(ty);
self
}
pub fn instance(&mut self, ty: &InstanceType) -> &mut Self {
self.ty().instance(ty);
self
}
pub fn function<'a, P, T>(
&mut self,
params: P,
result: impl Into<InterfaceTypeRef>,
) -> &mut Self
where
P: IntoIterator<Item = (Option<&'a str>, T)>,
P::IntoIter: ExactSizeIterator,
T: Into<InterfaceTypeRef>,
{
self.ty().function(params, result);
self
}
pub fn value(&mut self, ty: impl Into<InterfaceTypeRef>) -> &mut Self {
self.ty().value(ty);
self
}
#[must_use = "the encoder must be used to encode the type"]
pub fn interface_type(&mut self) -> InterfaceTypeEncoder<'_> {
self.ty().interface_type()
}
}
impl Encode for ComponentTypeSection {
fn encode(&self, sink: &mut Vec<u8>) {
encode_section(sink, ComponentSectionId::Type, self.num_added, &self.bytes);
}
}
impl ComponentSection for ComponentTypeSection {}