1use crate::{WasmInterfaceTypes, WitIdsToIndices, WitIndicesToIds};
2use anyhow::Result;
3use id_arena::{Arena, Id};
4
5#[derive(Debug, Default)]
6pub struct Types {
7 arena: Arena<Type>,
8}
9
10#[derive(Debug)]
11pub struct Type {
12 id: TypeId,
13 params: Box<[ValType]>,
14 results: Box<[ValType]>,
15}
16
17pub type TypeId = Id<Type>;
18
19#[derive(Debug, Copy, Clone)]
20pub enum ValType {
21 S8,
22 S16,
23 S32,
24 S64,
25 U8,
26 U16,
27 U32,
28 U64,
29 F32,
30 F64,
31 String,
32 Externref,
33 I32,
34 I64,
35}
36
37impl WasmInterfaceTypes {
38 pub(crate) fn parse_types(
39 &mut self,
40 types: wit_parser::Types,
41 wids: &mut WitIndicesToIds,
42 ) -> Result<()> {
43 for ty in types {
44 let ty = ty?;
45 let id = self.types.add(
46 ty.params.iter().cloned().map(parse2walrus).collect(),
47 ty.results.iter().cloned().map(parse2walrus).collect(),
48 );
49 wids.types.push(id);
50 }
51 Ok(())
52 }
53
54 pub(crate) fn encode_types(&self, writer: &mut wit_writer::Writer, wids: &mut WitIdsToIndices) {
55 let mut w = writer.types(self.types.arena.len() as u32);
56 for (id, ty) in self.types.arena.iter() {
57 w.add(
58 ty.params.len() as u32,
59 |w| {
60 for param in ty.params.iter() {
61 write_ty(w, param);
62 }
63 },
64 ty.results.len() as u32,
65 |w| {
66 for result in ty.results.iter() {
67 write_ty(w, result);
68 }
69 },
70 );
71 wids.push_ty(id);
72 }
73
74 fn write_ty(w: &mut wit_writer::Type<'_>, ty: &ValType) {
75 match ty {
76 ValType::S8 => w.s8(),
77 ValType::S16 => w.s16(),
78 ValType::S32 => w.s32(),
79 ValType::S64 => w.s64(),
80 ValType::U8 => w.u8(),
81 ValType::U16 => w.u16(),
82 ValType::U32 => w.u32(),
83 ValType::U64 => w.u64(),
84 ValType::F32 => w.f32(),
85 ValType::F64 => w.f64(),
86 ValType::String => w.string(),
87 ValType::Externref => w.externref(),
88 ValType::I32 => w.i32(),
89 ValType::I64 => w.i64(),
90 }
91 }
92 }
93}
94
95fn parse2walrus(parse: wit_parser::ValType) -> ValType {
96 match parse {
97 wit_parser::ValType::S8 => ValType::S8,
98 wit_parser::ValType::S16 => ValType::S16,
99 wit_parser::ValType::S32 => ValType::S32,
100 wit_parser::ValType::S64 => ValType::S64,
101 wit_parser::ValType::U8 => ValType::U8,
102 wit_parser::ValType::U16 => ValType::U16,
103 wit_parser::ValType::U32 => ValType::U32,
104 wit_parser::ValType::U64 => ValType::U64,
105 wit_parser::ValType::F32 => ValType::F32,
106 wit_parser::ValType::F64 => ValType::F64,
107 wit_parser::ValType::String => ValType::String,
108 wit_parser::ValType::Externref => ValType::Externref,
109 wit_parser::ValType::I32 => ValType::I32,
110 wit_parser::ValType::I64 => ValType::I64,
111 }
112}
113
114impl Types {
115 pub fn get(&self, id: TypeId) -> &Type {
117 &self.arena[id]
118 }
119
120 pub fn get_mut(&mut self, id: TypeId) -> &mut Type {
122 &mut self.arena[id]
123 }
124
125 pub fn iter(&self) -> impl Iterator<Item = &Type> {
135 self.arena.iter().map(|(_, f)| f)
136 }
137
138 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Type> {
140 self.arena.iter_mut().map(|(_, f)| f)
141 }
142
143 pub fn add(&mut self, params: Vec<ValType>, results: Vec<ValType>) -> TypeId {
145 self.arena.alloc_with_id(|id| Type {
146 id,
147 params: params.into_boxed_slice(),
148 results: results.into_boxed_slice(),
149 })
150 }
151}
152
153impl Type {
154 pub fn id(&self) -> TypeId {
156 self.id
157 }
158
159 pub fn params(&self) -> &[ValType] {
161 &self.params
162 }
163
164 pub fn results(&self) -> &[ValType] {
166 &self.results
167 }
168}