wit_walrus/
types.rs

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    /// Gets a reference to an type given its id
116    pub fn get(&self, id: TypeId) -> &Type {
117        &self.arena[id]
118    }
119
120    /// Gets a reference to an type given its id
121    pub fn get_mut(&mut self, id: TypeId) -> &mut Type {
122        &mut self.arena[id]
123    }
124
125    // /// Removes an type from this module.
126    // ///
127    // /// It is up to you to ensure that any potential references to the deleted
128    // /// type are also removed, eg `get_global` expressions.
129    // pub fn delete(&mut self, id: TypeId) {
130    //     self.arena.delete(id);
131    // }
132
133    /// Get a shared reference to this section's types.
134    pub fn iter(&self) -> impl Iterator<Item = &Type> {
135        self.arena.iter().map(|(_, f)| f)
136    }
137
138    /// Get mutable references to this section's types.
139    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Type> {
140        self.arena.iter_mut().map(|(_, f)| f)
141    }
142
143    /// Adds a new type to this section
144    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    /// Returns the identifier for this `Type`
155    pub fn id(&self) -> TypeId {
156        self.id
157    }
158
159    /// Returns parameters of this function type
160    pub fn params(&self) -> &[ValType] {
161        &self.params
162    }
163
164    /// Returns results of this function type
165    pub fn results(&self) -> &[ValType] {
166        &self.results
167    }
168}