diff --git a/src/decoders/binary.rs b/src/decoders/binary.rs index 3d53d1f..df2db2f 100644 --- a/src/decoders/binary.rs +++ b/src/decoders/binary.rs @@ -431,6 +431,7 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>( /// let input = &[ /// 0x00, // type section /// 0x01, // 1 type +/// 0x00, // function type /// 0x01, // list of 1 item /// 0x00, // S8 /// 0x01, // list of 1 item @@ -464,7 +465,7 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>( /// let output = Ok(( /// &[] as &[u8], /// Interfaces { -/// types: vec![Type { +/// types: vec![Type::Function { /// inputs: vec![InterfaceType::S8], /// outputs: vec![InterfaceType::S16], /// }], @@ -767,19 +768,29 @@ mod tests { #[test] fn test_types() { let input = &[ - 0x01, // 1 type + 0x02, // 2 type + 0x00, // function type 0x02, // list of 2 items 0x02, // S32 0x02, // S32 0x01, // list of 2 items 0x02, // S32 + 0x01, // record type + 0x02, // list of 2 items + 0x02, // S32 + 0x02, // S32 ]; let output = Ok(( &[] as &[u8], - vec![Type { - inputs: vec![InterfaceType::S32, InterfaceType::S32], - outputs: vec![InterfaceType::S32], - }], + vec![ + Type::Function { + inputs: vec![InterfaceType::S32, InterfaceType::S32], + outputs: vec![InterfaceType::S32], + }, + Type::Record { + fields: vec![InterfaceType::S32, InterfaceType::S32], + }, + ], )); assert_eq!(types::<()>(input), output); @@ -843,6 +854,7 @@ mod tests { let input = &[ 0x00, // type section 0x01, // 1 type + 0x00, // function type 0x01, // list of 1 item 0x00, // S8 0x01, // list of 1 item @@ -876,7 +888,7 @@ mod tests { let output = Ok(( &[] as &[u8], Interfaces { - types: vec![Type { + types: vec![Type::Function { inputs: vec![InterfaceType::S8], outputs: vec![InterfaceType::S16], }], diff --git a/src/decoders/wat.rs b/src/decoders/wat.rs index 3d1b149..7cbcfd5 100644 --- a/src/decoders/wat.rs +++ b/src/decoders/wat.rs @@ -427,15 +427,11 @@ impl<'a> Parse<'a> for Type { } else if lookahead.peek::() { parser.parse::()?; - let fields = parser.parens(|parser| { - let mut fields = vec![]; + let mut fields = vec![]; - while !parser.is_empty() { - fields.push(parser.parse()?); - } - - Ok(fields) - })?; + while !parser.is_empty() { + fields.push(parser.parse()?); + } Ok(Type::Record { fields }) } else { @@ -585,7 +581,7 @@ impl<'a> Parse<'a> for Interfaces<'a> { /// ) /// .unwrap(); /// let output = Interfaces { -/// types: vec![Type { +/// types: vec![Type::Function { /// inputs: vec![InterfaceType::I32], /// outputs: vec![InterfaceType::S8], /// }], @@ -782,9 +778,9 @@ mod tests { } #[test] - fn test_type() { + fn test_type_function() { let input = buffer(r#"(@interface type (func (param i32 i32) (result i32)))"#); - let output = Interface::Type(Type { + let output = Interface::Type(Type::Function { inputs: vec![InterfaceType::I32, InterfaceType::I32], outputs: vec![InterfaceType::I32], }); @@ -792,6 +788,16 @@ mod tests { assert_eq!(parser::parse::(&input).unwrap(), output); } + #[test] + fn test_type_record() { + let input = buffer(r#"(@interface type (record string i32))"#); + let output = Interface::Type(Type::Record { + fields: vec![InterfaceType::String, InterfaceType::I32], + }); + + assert_eq!(parser::parse::(&input).unwrap(), output); + } + #[test] fn test_export() { let input = buffer(r#"(@interface export "foo" (func 0))"#); @@ -862,7 +868,7 @@ mod tests { (@interface implement (func 0) (func 1))"#, ); let output = Interfaces { - types: vec![Type { + types: vec![Type::Function { inputs: vec![InterfaceType::I32], outputs: vec![InterfaceType::S8], }], diff --git a/src/encoders/binary.rs b/src/encoders/binary.rs index e016ac0..e012fa1 100644 --- a/src/encoders/binary.rs +++ b/src/encoders/binary.rs @@ -451,13 +451,14 @@ mod tests { } #[test] - fn test_type() { + fn test_type_function() { assert_to_bytes!( - Type { + Type::Function { inputs: vec![InterfaceType::I32, InterfaceType::I64], outputs: vec![InterfaceType::S32], }, &[ + 0x00, // function type 0x02, // list of 2 items 0x0c, // I32 0x0d, // I64 @@ -467,6 +468,21 @@ mod tests { ); } + #[test] + fn test_type_record() { + assert_to_bytes!( + Type::Record { + fields: vec![InterfaceType::I32, InterfaceType::I64], + }, + &[ + 0x01, // record type + 0x02, // list of 2 items + 0x0c, // I32 + 0x0d, // I64 + ] + ); + } + #[test] fn test_import() { assert_to_bytes!( @@ -504,7 +520,7 @@ mod tests { fn test_interfaces() { assert_to_bytes!( Interfaces { - types: vec![Type { + types: vec![Type::Function { inputs: vec![InterfaceType::S8], outputs: vec![InterfaceType::S16], }], @@ -529,6 +545,7 @@ mod tests { &[ 0x00, // type section 0x01, // 1 type + 0x00, // function type 0x01, // list of 1 item 0x00, // S8 0x01, // list of 1 item diff --git a/src/encoders/wat.rs b/src/encoders/wat.rs index a67ce5b..8cc6679 100644 --- a/src/encoders/wat.rs +++ b/src/encoders/wat.rs @@ -10,7 +10,7 @@ //! }; //! //! let input: String = (&Interfaces { -//! types: vec![Type { +//! types: vec![Type::Function { //! inputs: vec![InterfaceType::I32], //! outputs: vec![InterfaceType::S8], //! }], @@ -175,7 +175,7 @@ impl<'input> ToString for &Type { ), Type::Record { fields } => format!( - r#"(@interface type (record {fields}))"#, + r#"(@interface type (record{fields}))"#, fields = fields .iter() .fold(String::new(), |mut accumulator, interface_type| { @@ -453,26 +453,30 @@ mod tests { #[test] fn test_types() { let inputs: Vec = vec![ - (&Type { + (&Type::Function { inputs: vec![InterfaceType::I32, InterfaceType::F32], outputs: vec![InterfaceType::I32], }) .to_string(), - (&Type { + (&Type::Function { inputs: vec![InterfaceType::I32], outputs: vec![], }) .to_string(), - (&Type { + (&Type::Function { inputs: vec![], outputs: vec![InterfaceType::I32], }) .to_string(), - (&Type { + (&Type::Function { inputs: vec![], outputs: vec![], }) .to_string(), + (&Type::Record { + fields: vec![InterfaceType::String, InterfaceType::I32], + }) + .to_string(), ]; let outputs = vec![ r#"(@interface type (func @@ -483,6 +487,7 @@ mod tests { r#"(@interface type (func (result i32)))"#, r#"(@interface type (func))"#, + r#"(@interface type (record string i32))"#, ]; assert_eq!(inputs, outputs); @@ -529,7 +534,7 @@ mod tests { #[test] fn test_interfaces() { let input: String = (&Interfaces { - types: vec![Type { + types: vec![Type::Function { inputs: vec![InterfaceType::I32], outputs: vec![InterfaceType::S8], }], diff --git a/tests/binary.rs b/tests/binary.rs index 0e89173..96d1c77 100644 --- a/tests/binary.rs +++ b/tests/binary.rs @@ -7,14 +7,17 @@ use wasmer_interface_types::{ fn test_binary_encoding_decoding_roundtrip() { let original_ast = Interfaces { types: vec![ - Type { + Type::Function { inputs: vec![], outputs: vec![], }, - Type { + Type::Function { inputs: vec![InterfaceType::I32, InterfaceType::I32], outputs: vec![InterfaceType::S32], }, + Type::Record { + fields: vec![InterfaceType::String, InterfaceType::I32], + }, ], imports: vec![Import { namespace: "a",