use std::io; use super::{ Deserialize, Serialize, Error, VarUint7, VarInt7, VarUint1, CountedList, CountedListWriter }; pub enum Type { Function(FunctionType), } impl Deserialize for Type { type Error = Error; fn deserialize(reader: &mut R) -> Result { Ok(Type::Function(FunctionType::deserialize(reader)?)) } } impl Serialize for Type { type Error = Error; fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { match self { Type::Function(fn_type) => fn_type.serialize(writer) } } } #[derive(Clone, Copy, PartialEq, Debug)] pub enum ValueType { I32, I64, F32, F64, } impl Deserialize for ValueType { type Error = Error; fn deserialize(reader: &mut R) -> Result { let val = VarInt7::deserialize(reader)?; match val.into() { -0x01 => Ok(ValueType::I32), -0x02 => Ok(ValueType::I64), -0x03 => Ok(ValueType::F32), -0x04 => Ok(ValueType::F64), _ => Err(Error::UnknownValueType(val.into())), } } } impl Serialize for ValueType { type Error = Error; fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let val: VarInt7 = match self { ValueType::I32 => -0x01, ValueType::I64 => -0x02, ValueType::F32 => -0x03, ValueType::F64 => -0x04, }.into(); val.serialize(writer)?; Ok(()) } } #[derive(Clone, Copy, PartialEq, Debug)] pub enum BlockType { Value(ValueType), NoResult, } impl Deserialize for BlockType { type Error = Error; fn deserialize(reader: &mut R) -> Result { let val = VarInt7::deserialize(reader)?; match val.into() { -0x01 => Ok(BlockType::Value(ValueType::I32)), -0x02 => Ok(BlockType::Value(ValueType::I64)), -0x03 => Ok(BlockType::Value(ValueType::F32)), -0x04 => Ok(BlockType::Value(ValueType::F64)), -0x40 => Ok(BlockType::NoResult), _ => Err(Error::UnknownValueType(val.into())), } } } impl Serialize for BlockType { type Error = Error; fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { let val: VarInt7 = match self { BlockType::NoResult => -0x40i8, BlockType::Value(ValueType::I32) => -0x01, BlockType::Value(ValueType::I64) => -0x02, BlockType::Value(ValueType::F32) => -0x03, BlockType::Value(ValueType::F64) => -0x04, }.into(); val.serialize(writer)?; Ok(()) } } pub struct FunctionType { form: u8, params: Vec, return_type: Option, } impl FunctionType { pub fn form(&self) -> u8 { self.form } pub fn params(&self) -> &[ValueType] { &self.params } pub fn return_type(&self) -> Option { self.return_type } } impl Deserialize for FunctionType { type Error = Error; fn deserialize(reader: &mut R) -> Result { let form: u8 = VarUint7::deserialize(reader)?.into(); let params: Vec = CountedList::deserialize(reader)?.into_inner(); let has_return_type = VarUint1::deserialize(reader)?; let return_type = if has_return_type.into() { Some(ValueType::deserialize(reader)?) } else { None }; Ok(FunctionType { form: form, params: params, return_type: return_type, }) } } impl Serialize for FunctionType { type Error = Error; fn serialize(self, writer: &mut W) -> Result<(), Self::Error> { VarUint7::from(self.form).serialize(writer)?; let data = self.params; let counted_list = CountedListWriter::( data.len(), data.into_iter().map(Into::into), ); counted_list.serialize(writer)?; if let Some(return_type) = self.return_type { VarUint1::from(true).serialize(writer)?; return_type.serialize(writer)?; } else { VarUint1::from(false).serialize(writer)?; } Ok(()) } }