1use super::{
2 CountedList, CountedListWriter, Deserialize, Error, Serialize, VarInt32, VarInt7, VarUint7,
3};
4use crate::io;
5use alloc::vec::Vec;
6use core::fmt;
7
8#[derive(Debug, Clone, PartialEq, Hash, Eq)]
10pub enum Type {
11 Function(FunctionType),
13}
14
15impl Deserialize for Type {
16 type Error = Error;
17
18 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
19 Ok(Type::Function(FunctionType::deserialize(reader)?))
20 }
21}
22
23impl Serialize for Type {
24 type Error = Error;
25
26 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
27 match self {
28 Type::Function(fn_type) => fn_type.serialize(writer),
29 }
30 }
31}
32
33#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq)]
35pub enum ValueType {
36 I32,
38 I64,
40 F32,
42 F64,
44 #[cfg(feature = "simd")]
45 V128,
47}
48
49impl Deserialize for ValueType {
50 type Error = Error;
51
52 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
53 let val = VarInt7::deserialize(reader)?;
54
55 match val.into() {
56 -0x01 => Ok(ValueType::I32),
57 -0x02 => Ok(ValueType::I64),
58 -0x03 => Ok(ValueType::F32),
59 -0x04 => Ok(ValueType::F64),
60 #[cfg(feature = "simd")]
61 -0x05 => Ok(ValueType::V128),
62 _ => Err(Error::UnknownValueType(val.into())),
63 }
64 }
65}
66
67impl Serialize for ValueType {
68 type Error = Error;
69
70 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
71 let val: VarInt7 = match self {
72 ValueType::I32 => -0x01,
73 ValueType::I64 => -0x02,
74 ValueType::F32 => -0x03,
75 ValueType::F64 => -0x04,
76 #[cfg(feature = "simd")]
77 ValueType::V128 => -0x05,
78 }
79 .into();
80 val.serialize(writer)?;
81 Ok(())
82 }
83}
84
85impl fmt::Display for ValueType {
86 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87 match *self {
88 ValueType::I32 => write!(f, "i32"),
89 ValueType::I64 => write!(f, "i64"),
90 ValueType::F32 => write!(f, "f32"),
91 ValueType::F64 => write!(f, "f64"),
92 #[cfg(feature = "simd")]
93 ValueType::V128 => write!(f, "v128"),
94 }
95 }
96}
97
98#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
100pub enum BlockType {
101 NoResult,
103 Value(ValueType),
105 #[cfg(feature = "multi_value")]
107 TypeIndex(u32),
108}
109
110impl Deserialize for BlockType {
111 type Error = Error;
112
113 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
114 let val = VarInt32::deserialize(reader)?;
115
116 match val.into() {
117 -0x40 => Ok(BlockType::NoResult),
118 -0x01 => Ok(BlockType::Value(ValueType::I32)),
119 -0x02 => Ok(BlockType::Value(ValueType::I64)),
120 -0x03 => Ok(BlockType::Value(ValueType::F32)),
121 -0x04 => Ok(BlockType::Value(ValueType::F64)),
122 #[cfg(feature = "simd")]
123 -0x05 => Ok(BlockType::Value(ValueType::V128)),
124 #[cfg(feature = "multi_value")]
125 idx => {
126 let idx = idx.try_into().map_err(|_| Error::UnknownBlockType(idx))?;
127 Ok(BlockType::TypeIndex(idx))
128 },
129 #[cfg(not(feature = "multi_value"))]
130 _ => Err(Error::UnknownBlockType(val.into())),
131 }
132 }
133}
134
135impl Serialize for BlockType {
136 type Error = Error;
137
138 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
139 let val: VarInt32 = match self {
140 BlockType::NoResult => -0x40,
141 BlockType::Value(ValueType::I32) => -0x01,
142 BlockType::Value(ValueType::I64) => -0x02,
143 BlockType::Value(ValueType::F32) => -0x03,
144 BlockType::Value(ValueType::F64) => -0x04,
145 #[cfg(feature = "simd")]
146 BlockType::Value(ValueType::V128) => -0x05,
147 #[cfg(feature = "multi_value")]
148 BlockType::TypeIndex(idx) => idx as i32,
149 }
150 .into();
151 val.serialize(writer)?;
152 Ok(())
153 }
154}
155
156#[derive(Debug, Clone, PartialEq, Hash, Eq)]
158pub struct FunctionType {
159 form: u8,
160 params: Vec<ValueType>,
161 results: Vec<ValueType>,
162}
163
164impl Default for FunctionType {
165 fn default() -> Self {
166 FunctionType { form: 0x60, params: Vec::new(), results: Vec::new() }
167 }
168}
169
170impl FunctionType {
171 pub fn new(params: Vec<ValueType>, results: Vec<ValueType>) -> Self {
173 FunctionType { form: 0x60, params, results }
174 }
175 pub fn form(&self) -> u8 {
177 self.form
178 }
179 pub fn params(&self) -> &[ValueType] {
181 &self.params
182 }
183 pub fn params_mut(&mut self) -> &mut Vec<ValueType> {
185 &mut self.params
186 }
187 pub fn results(&self) -> &[ValueType] {
189 &self.results
190 }
191 pub fn results_mut(&mut self) -> &mut Vec<ValueType> {
193 &mut self.results
194 }
195}
196
197impl Deserialize for FunctionType {
198 type Error = Error;
199
200 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
201 let form: u8 = VarUint7::deserialize(reader)?.into();
202
203 if form != 0x60 {
204 return Err(Error::UnknownFunctionForm(form))
205 }
206
207 let params: Vec<ValueType> = CountedList::deserialize(reader)?.into_inner();
208 let results: Vec<ValueType> = CountedList::deserialize(reader)?.into_inner();
209
210 #[cfg(not(feature = "multi_value"))]
211 if results.len() > 1 {
212 return Err(Error::Other(
213 "Enable the multi_value feature to deserialize more than one function result",
214 ))
215 }
216
217 Ok(FunctionType { form, params, results })
218 }
219}
220
221impl Serialize for FunctionType {
222 type Error = Error;
223
224 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
225 VarUint7::from(self.form).serialize(writer)?;
226
227 let params_counted_list = CountedListWriter::<ValueType, _>(
228 self.params.len(),
229 self.params.into_iter().map(Into::into),
230 );
231 params_counted_list.serialize(writer)?;
232
233 let results_counted_list = CountedListWriter::<ValueType, _>(
234 self.results.len(),
235 self.results.into_iter().map(Into::into),
236 );
237 results_counted_list.serialize(writer)?;
238
239 Ok(())
240 }
241}
242
243#[derive(Clone, Copy, Debug, PartialEq)]
245pub enum TableElementType {
246 AnyFunc,
248}
249
250impl Deserialize for TableElementType {
251 type Error = Error;
252
253 fn deserialize<R: io::Read>(reader: &mut R) -> Result<Self, Self::Error> {
254 let val = VarInt7::deserialize(reader)?;
255
256 match val.into() {
257 -0x10 => Ok(TableElementType::AnyFunc),
258 _ => Err(Error::UnknownTableElementType(val.into())),
259 }
260 }
261}
262
263impl Serialize for TableElementType {
264 type Error = Error;
265
266 fn serialize<W: io::Write>(self, writer: &mut W) -> Result<(), Self::Error> {
267 let val: VarInt7 = match self {
268 TableElementType::AnyFunc => -0x10,
269 }
270 .into();
271 val.serialize(writer)?;
272 Ok(())
273 }
274}