use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Component {
pub name: String,
pub modules: Vec<CoreModule>,
pub components: Vec<Component>,
pub instances: Vec<ComponentInstance>,
pub interfaces: HashMap<String, WITInterface>,
pub imports: Vec<Import>,
pub exports: Vec<Export>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CoreModule {
pub id: String,
pub binary: Vec<u8>,
pub functions: Vec<Function>,
pub memories: Vec<Memory>,
pub tables: Vec<Table>,
pub globals: Vec<Global>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Function {
pub index: u32,
pub name: Option<String>,
pub signature: FunctionSignature,
pub exported: bool,
pub imported: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FunctionSignature {
pub params: Vec<ValueType>,
pub results: Vec<ValueType>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ValueType {
I32,
I64,
F32,
F64,
V128,
FuncRef,
ExternRef,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Memory {
pub index: u32,
pub initial: u32,
pub maximum: Option<u32>,
pub shared: bool,
pub memory64: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Table {
pub index: u32,
pub element_type: ValueType,
pub initial: u32,
pub maximum: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Global {
pub index: u32,
pub value_type: ValueType,
pub mutable: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComponentInstance {
pub id: String,
pub component: String,
#[serde(default)]
pub recursive_reentrance: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WITInterface {
pub name: String,
pub functions: Vec<WITFunction>,
pub types: Vec<WITType>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WITFunction {
pub name: String,
pub params: Vec<(String, WITType)>,
pub results: Vec<WITType>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum WITType {
Bool,
U8,
U16,
U32,
U64,
S8,
S16,
S32,
S64,
F32,
F64,
String,
List(Box<WITType>),
Record(Vec<(String, WITType)>),
Variant(Vec<(String, Option<WITType>)>),
Enum(Vec<String>),
Option(Box<WITType>),
Result { ok: Box<WITType>, err: Box<WITType> },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Import {
pub name: String,
pub kind: ImportKind,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ImportKind {
Function(FunctionSignature),
Memory(Memory),
Table(Table),
Global(Global),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Export {
pub name: String,
pub kind: ExportKind,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ExportKind {
Function(u32),
Memory(u32),
Table(u32),
Global(u32),
}
impl Component {
pub fn new(name: String) -> Self {
Self {
name,
modules: Vec::new(),
components: Vec::new(),
instances: Vec::new(),
interfaces: HashMap::new(),
imports: Vec::new(),
exports: Vec::new(),
}
}
pub fn total_memories(&self) -> usize {
self.modules.iter().map(|m| m.memories.len()).sum()
}
pub fn total_memory_size(&self) -> u64 {
self.modules
.iter()
.flat_map(|m| &m.memories)
.map(|mem| mem.initial as u64 * 65536) .sum()
}
}