mirror of
https://github.com/fluencelabs/interface-types
synced 2024-12-04 15:20:20 +00:00
feat(interface-types) Introduce RecordType
for InterfaceType
and Type
.
The `Type::Record` variant now is defined by `RecordType`. In addition, `InterfaceType` has a new variant: `Record`, that is also defined by `RecordType`. Encoders and decoders are updated to consider `RecordType`, which removes code duplication and simplify code.
This commit is contained in:
parent
b528e965c5
commit
41f9c231c0
15
src/ast.rs
15
src/ast.rs
@ -48,6 +48,16 @@ pub enum InterfaceType {
|
||||
|
||||
/// A 64-bits integer (as defiend in WebAssembly core).
|
||||
I64,
|
||||
|
||||
/// A record.
|
||||
Record(RecordType),
|
||||
}
|
||||
|
||||
/// Representing a record type.
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub struct RecordType {
|
||||
/// Types representing the fields.
|
||||
pub fields: Vec<InterfaceType>,
|
||||
}
|
||||
|
||||
/// Represents the kind of type.
|
||||
@ -81,10 +91,7 @@ pub enum Type {
|
||||
/// ```wasm,ignore
|
||||
/// (@interface type (record string i32))
|
||||
/// ```
|
||||
Record {
|
||||
/// Types representing the fields.
|
||||
fields: Vec<InterfaceType>,
|
||||
},
|
||||
Record(RecordType),
|
||||
}
|
||||
|
||||
/// Represents an imported function.
|
||||
|
@ -7,31 +7,6 @@ use nom::{
|
||||
};
|
||||
use std::{convert::TryFrom, str};
|
||||
|
||||
/// Parse an `InterfaceType`.
|
||||
impl TryFrom<u8> for InterfaceType {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(code: u8) -> Result<Self, Self::Error> {
|
||||
Ok(match code {
|
||||
0 => Self::S8,
|
||||
1 => Self::S16,
|
||||
2 => Self::S32,
|
||||
3 => Self::S64,
|
||||
4 => Self::U8,
|
||||
5 => Self::U16,
|
||||
6 => Self::U32,
|
||||
7 => Self::U64,
|
||||
8 => Self::F32,
|
||||
9 => Self::F64,
|
||||
10 => Self::String,
|
||||
11 => Self::Anyref,
|
||||
12 => Self::I32,
|
||||
13 => Self::I64,
|
||||
_ => return Err("Unknown interface type code."),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a type kind.
|
||||
impl TryFrom<u8> for TypeKind {
|
||||
type Error = &'static str;
|
||||
@ -95,6 +70,51 @@ fn uleb<'input, E: ParseError<&'input [u8]>>(input: &'input [u8]) -> IResult<&'i
|
||||
))
|
||||
}
|
||||
|
||||
/// Parse an interface type.
|
||||
fn ty<'input, E: ParseError<&'input [u8]>>(
|
||||
mut input: &'input [u8],
|
||||
) -> IResult<&'input [u8], InterfaceType, E> {
|
||||
if input.is_empty() {
|
||||
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
|
||||
}
|
||||
|
||||
consume!((input, opcode) = byte(input)?);
|
||||
|
||||
let ty = match opcode {
|
||||
0x00 => InterfaceType::S8,
|
||||
0x01 => InterfaceType::S16,
|
||||
0x02 => InterfaceType::S32,
|
||||
0x03 => InterfaceType::S64,
|
||||
0x04 => InterfaceType::U8,
|
||||
0x05 => InterfaceType::U16,
|
||||
0x06 => InterfaceType::U32,
|
||||
0x07 => InterfaceType::U64,
|
||||
0x08 => InterfaceType::F32,
|
||||
0x09 => InterfaceType::F64,
|
||||
0x0a => InterfaceType::String,
|
||||
0x0b => InterfaceType::Anyref,
|
||||
0x0c => InterfaceType::I32,
|
||||
0x0d => InterfaceType::I64,
|
||||
0x0e => {
|
||||
consume!((input, record_type) = record_type(input)?);
|
||||
|
||||
InterfaceType::Record(record_type)
|
||||
}
|
||||
_ => return Err(Err::Error(make_error(input, ErrorKind::ParseTo))),
|
||||
};
|
||||
|
||||
Ok((input, ty))
|
||||
}
|
||||
|
||||
/// Parse an record type.
|
||||
fn record_type<'input, E: ParseError<&'input [u8]>>(
|
||||
input: &'input [u8],
|
||||
) -> IResult<&'input [u8], RecordType, E> {
|
||||
let (output, fields) = list(input, ty)?;
|
||||
|
||||
Ok((output, RecordType { fields }))
|
||||
}
|
||||
|
||||
/// Parse a UTF-8 string.
|
||||
fn string<'input, E: ParseError<&'input [u8]>>(
|
||||
input: &'input [u8],
|
||||
@ -144,22 +164,6 @@ fn list<'input, I, E: ParseError<&'input [u8]>>(
|
||||
Ok((input, items))
|
||||
}
|
||||
|
||||
/// Parse a type.
|
||||
fn ty<'input, E: ParseError<&'input [u8]>>(
|
||||
input: &'input [u8],
|
||||
) -> IResult<&'input [u8], InterfaceType, E> {
|
||||
if input.is_empty() {
|
||||
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
|
||||
}
|
||||
|
||||
let (output, ty) = byte(input)?;
|
||||
|
||||
match InterfaceType::try_from(ty) {
|
||||
Ok(ty) => Ok((output, ty)),
|
||||
Err(_) => Err(Err::Error(make_error(input, ErrorKind::ParseTo))),
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse an instruction with its arguments.
|
||||
fn instruction<'input, E: ParseError<&'input [u8]>>(
|
||||
input: &'input [u8],
|
||||
@ -261,9 +265,9 @@ fn types<'input, E: ParseError<&'input [u8]>>(
|
||||
}
|
||||
|
||||
TypeKind::Record => {
|
||||
consume!((input, fields) = list(input, ty)?);
|
||||
consume!((input, record_type) = record_type(input)?);
|
||||
|
||||
types.push(Type::Record { fields });
|
||||
types.push(Type::Record(record_type));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -575,6 +579,95 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ty() {
|
||||
let input = &[
|
||||
0x0f, // list of 15 items
|
||||
0x00, // S8
|
||||
0x01, // S16
|
||||
0x02, // S32
|
||||
0x03, // S64
|
||||
0x04, // U8
|
||||
0x05, // U16
|
||||
0x06, // U32
|
||||
0x07, // U64
|
||||
0x08, // F32
|
||||
0x09, // F64
|
||||
0x0a, // String
|
||||
0x0b, // Anyref
|
||||
0x0c, // I32
|
||||
0x0d, // I64
|
||||
0x0e, 0x01, 0x02, // Record
|
||||
0x01,
|
||||
];
|
||||
let output = Ok((
|
||||
&[0x01][..],
|
||||
vec![
|
||||
InterfaceType::S8,
|
||||
InterfaceType::S16,
|
||||
InterfaceType::S32,
|
||||
InterfaceType::S64,
|
||||
InterfaceType::U8,
|
||||
InterfaceType::U16,
|
||||
InterfaceType::U32,
|
||||
InterfaceType::U64,
|
||||
InterfaceType::F32,
|
||||
InterfaceType::F64,
|
||||
InterfaceType::String,
|
||||
InterfaceType::Anyref,
|
||||
InterfaceType::I32,
|
||||
InterfaceType::I64,
|
||||
InterfaceType::Record(RecordType {
|
||||
fields: vec![InterfaceType::S32],
|
||||
}),
|
||||
],
|
||||
));
|
||||
|
||||
assert_eq!(list::<_, ()>(input, ty), output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_record_type() {
|
||||
let input = &[
|
||||
0x03, // list of 3 items
|
||||
0x01, // 1 field
|
||||
0x0a, // String
|
||||
0x02, // 2 fields
|
||||
0x0a, // String
|
||||
0x0c, // I32
|
||||
0x03, // 3 fields
|
||||
0x0a, // String
|
||||
0x0e, // Record
|
||||
0x02, // 2 fields
|
||||
0x0c, // I32
|
||||
0x0c, // I32
|
||||
0x09, // F64
|
||||
0x01,
|
||||
];
|
||||
let output = Ok((
|
||||
&[0x01][..],
|
||||
vec![
|
||||
RecordType {
|
||||
fields: vec![InterfaceType::String],
|
||||
},
|
||||
RecordType {
|
||||
fields: vec![InterfaceType::String, InterfaceType::I32],
|
||||
},
|
||||
RecordType {
|
||||
fields: vec![
|
||||
InterfaceType::String,
|
||||
InterfaceType::Record(RecordType {
|
||||
fields: vec![InterfaceType::I32, InterfaceType::I32],
|
||||
}),
|
||||
InterfaceType::F64,
|
||||
],
|
||||
},
|
||||
],
|
||||
));
|
||||
|
||||
assert_eq!(list::<_, ()>(input, record_type), output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_string() {
|
||||
let input = &[
|
||||
@ -602,50 +695,7 @@ mod tests {
|
||||
];
|
||||
let output = Ok((&[0x07][..], vec!["a", "bc"]));
|
||||
|
||||
assert_eq!(list::<&str, ()>(input, string), output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ty() {
|
||||
let input = &[
|
||||
0x0e, // list of 14 items
|
||||
0x00, // S8
|
||||
0x01, // S16
|
||||
0x02, // S32
|
||||
0x03, // S64
|
||||
0x04, // U8
|
||||
0x05, // U16
|
||||
0x06, // U32
|
||||
0x07, // U64
|
||||
0x08, // F32
|
||||
0x09, // F64
|
||||
0x0a, // String
|
||||
0x0b, // Anyref
|
||||
0x0c, // I32
|
||||
0x0d, // I64
|
||||
0x01,
|
||||
];
|
||||
let output = Ok((
|
||||
&[0x01][..],
|
||||
vec![
|
||||
InterfaceType::S8,
|
||||
InterfaceType::S16,
|
||||
InterfaceType::S32,
|
||||
InterfaceType::S64,
|
||||
InterfaceType::U8,
|
||||
InterfaceType::U16,
|
||||
InterfaceType::U32,
|
||||
InterfaceType::U64,
|
||||
InterfaceType::F32,
|
||||
InterfaceType::F64,
|
||||
InterfaceType::String,
|
||||
InterfaceType::Anyref,
|
||||
InterfaceType::I32,
|
||||
InterfaceType::I64,
|
||||
],
|
||||
));
|
||||
|
||||
assert_eq!(list::<InterfaceType, ()>(input, ty), output);
|
||||
assert_eq!(list::<_, ()>(input, string), output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -734,7 +784,7 @@ mod tests {
|
||||
],
|
||||
));
|
||||
|
||||
assert_eq!(list::<Instruction, ()>(input, instruction), output);
|
||||
assert_eq!(list::<_, ()>(input, instruction), output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -787,9 +837,9 @@ mod tests {
|
||||
inputs: vec![InterfaceType::S32, InterfaceType::S32],
|
||||
outputs: vec![InterfaceType::S32],
|
||||
},
|
||||
Type::Record {
|
||||
Type::Record(RecordType {
|
||||
fields: vec![InterfaceType::S32, InterfaceType::S32],
|
||||
},
|
||||
}),
|
||||
],
|
||||
));
|
||||
|
||||
|
@ -14,6 +14,7 @@ mod keyword {
|
||||
custom_keyword!(implement);
|
||||
custom_keyword!(r#type = "type");
|
||||
custom_keyword!(record);
|
||||
custom_keyword!(field);
|
||||
|
||||
// New types.
|
||||
custom_keyword!(s8);
|
||||
@ -126,12 +127,32 @@ impl Parse<'_> for InterfaceType {
|
||||
parser.parse::<keyword::i64>()?;
|
||||
|
||||
Ok(InterfaceType::I64)
|
||||
} else if lookahead.peek::<keyword::record>() {
|
||||
Ok(InterfaceType::Record(parser.parse()?))
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse<'_> for RecordType {
|
||||
fn parse(parser: Parser<'_>) -> Result<Self> {
|
||||
parser.parse::<keyword::record>()?;
|
||||
|
||||
let mut fields = vec![];
|
||||
|
||||
while !parser.is_empty() {
|
||||
fields.push(parser.parens(|parser| {
|
||||
parser.parse::<keyword::field>()?;
|
||||
|
||||
parser.parse()
|
||||
})?);
|
||||
}
|
||||
|
||||
Ok(RecordType { fields })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for Instruction {
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
fn parse(parser: Parser<'a>) -> Result<Self> {
|
||||
@ -425,15 +446,7 @@ impl<'a> Parse<'a> for Type {
|
||||
outputs: output_types,
|
||||
})
|
||||
} else if lookahead.peek::<keyword::record>() {
|
||||
parser.parse::<keyword::record>()?;
|
||||
|
||||
let mut fields = vec![];
|
||||
|
||||
while !parser.is_empty() {
|
||||
fields.push(parser.parse()?);
|
||||
}
|
||||
|
||||
Ok(Type::Record { fields })
|
||||
Ok(Type::Record(parser.parse()?))
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
@ -622,8 +635,21 @@ mod tests {
|
||||
#[test]
|
||||
fn test_interface_type() {
|
||||
let inputs = vec![
|
||||
"s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64", "f32", "f64", "string", "anyref",
|
||||
"i32", "i64",
|
||||
"s8",
|
||||
"s16",
|
||||
"s32",
|
||||
"s64",
|
||||
"u8",
|
||||
"u16",
|
||||
"u32",
|
||||
"u64",
|
||||
"f32",
|
||||
"f64",
|
||||
"string",
|
||||
"anyref",
|
||||
"i32",
|
||||
"i64",
|
||||
"record (field string)",
|
||||
];
|
||||
let outputs = vec![
|
||||
InterfaceType::S8,
|
||||
@ -640,6 +666,9 @@ mod tests {
|
||||
InterfaceType::Anyref,
|
||||
InterfaceType::I32,
|
||||
InterfaceType::I64,
|
||||
InterfaceType::Record(RecordType {
|
||||
fields: vec![InterfaceType::String],
|
||||
}),
|
||||
];
|
||||
|
||||
assert_eq!(inputs.len(), outputs.len());
|
||||
@ -652,6 +681,41 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_record_type() {
|
||||
let inputs = vec![
|
||||
"record (field string)",
|
||||
"record (field string) (field i32)",
|
||||
"record (field string) (field record (field i32) (field i32)) (field f64)",
|
||||
];
|
||||
let outputs = vec![
|
||||
RecordType {
|
||||
fields: vec![InterfaceType::String],
|
||||
},
|
||||
RecordType {
|
||||
fields: vec![InterfaceType::String, InterfaceType::I32],
|
||||
},
|
||||
RecordType {
|
||||
fields: vec![
|
||||
InterfaceType::String,
|
||||
InterfaceType::Record(RecordType {
|
||||
fields: vec![InterfaceType::I32, InterfaceType::I32],
|
||||
}),
|
||||
InterfaceType::F64,
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
assert_eq!(inputs.len(), outputs.len());
|
||||
|
||||
for (input, output) in inputs.iter().zip(outputs.iter()) {
|
||||
assert_eq!(
|
||||
&parser::parse::<RecordType>(&buffer(input)).unwrap(),
|
||||
output
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_instructions() {
|
||||
let inputs = vec![
|
||||
@ -790,10 +854,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_type_record() {
|
||||
let input = buffer(r#"(@interface type (record string i32))"#);
|
||||
let output = Interface::Type(Type::Record {
|
||||
let input = buffer(r#"(@interface type (record (field string) (field i32)))"#);
|
||||
let output = Interface::Type(Type::Record(RecordType {
|
||||
fields: vec![InterfaceType::String, InterfaceType::I32],
|
||||
});
|
||||
}));
|
||||
|
||||
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
|
||||
}
|
||||
|
@ -108,10 +108,24 @@ where
|
||||
InterfaceType::Anyref => 0x0b_u8.to_bytes(writer),
|
||||
InterfaceType::I32 => 0x0c_u8.to_bytes(writer),
|
||||
InterfaceType::I64 => 0x0d_u8.to_bytes(writer),
|
||||
InterfaceType::Record(record_type) => {
|
||||
0x0e_u8.to_bytes(writer)?;
|
||||
record_type.to_bytes(writer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Encode a `RecordType` into bytes.
|
||||
impl<W> ToBytes<W> for RecordType
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
|
||||
self.fields.to_bytes(writer)
|
||||
}
|
||||
}
|
||||
|
||||
/// Encode a `TypeKind` into bytes.
|
||||
impl<W> ToBytes<W> for TypeKind
|
||||
where
|
||||
@ -156,7 +170,7 @@ where
|
||||
outputs.to_bytes(writer)?;
|
||||
}
|
||||
|
||||
Type::Record { fields } => {
|
||||
Type::Record(RecordType { fields }) => {
|
||||
TypeKind::Record.to_bytes(writer)?;
|
||||
fields.to_bytes(writer)?;
|
||||
}
|
||||
@ -422,6 +436,55 @@ mod tests {
|
||||
assert_to_bytes!(InterfaceType::Anyref, &[0x0b]);
|
||||
assert_to_bytes!(InterfaceType::I32, &[0x0c]);
|
||||
assert_to_bytes!(InterfaceType::I64, &[0x0d]);
|
||||
assert_to_bytes!(
|
||||
InterfaceType::Record(RecordType {
|
||||
fields: vec![InterfaceType::String]
|
||||
}),
|
||||
&[0x0e, 0x01, 0x0a]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_record_type() {
|
||||
assert_to_bytes!(
|
||||
RecordType {
|
||||
fields: vec![InterfaceType::String]
|
||||
},
|
||||
&[
|
||||
0x01, // 1 field
|
||||
0x0a, // String
|
||||
]
|
||||
);
|
||||
assert_to_bytes!(
|
||||
RecordType {
|
||||
fields: vec![InterfaceType::String, InterfaceType::I32]
|
||||
},
|
||||
&[
|
||||
0x02, // 2 fields
|
||||
0x0a, // String
|
||||
0x0c, // I32
|
||||
]
|
||||
);
|
||||
assert_to_bytes!(
|
||||
RecordType {
|
||||
fields: vec![
|
||||
InterfaceType::String,
|
||||
InterfaceType::Record(RecordType {
|
||||
fields: vec![InterfaceType::I32, InterfaceType::I32],
|
||||
}),
|
||||
InterfaceType::F64,
|
||||
],
|
||||
},
|
||||
&[
|
||||
0x03, // 3 fields
|
||||
0x0a, // String
|
||||
0x0e, // Record
|
||||
0x02, // 2 fields
|
||||
0x0c, // I32
|
||||
0x0c, // I32
|
||||
0x09, // F64
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -471,9 +534,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_type_record() {
|
||||
assert_to_bytes!(
|
||||
Type::Record {
|
||||
Type::Record(RecordType {
|
||||
fields: vec![InterfaceType::I32, InterfaceType::I64],
|
||||
},
|
||||
}),
|
||||
&[
|
||||
0x01, // record type
|
||||
0x02, // list of 2 items
|
||||
|
@ -61,24 +61,41 @@ use std::string::ToString;
|
||||
impl ToString for &InterfaceType {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
InterfaceType::S8 => "s8".into(),
|
||||
InterfaceType::S16 => "s16".into(),
|
||||
InterfaceType::S32 => "s32".into(),
|
||||
InterfaceType::S64 => "s64".into(),
|
||||
InterfaceType::U8 => "u8".into(),
|
||||
InterfaceType::U16 => "u16".into(),
|
||||
InterfaceType::U32 => "u32".into(),
|
||||
InterfaceType::U64 => "u64".into(),
|
||||
InterfaceType::F32 => "f32".into(),
|
||||
InterfaceType::F64 => "f64".into(),
|
||||
InterfaceType::String => "string".into(),
|
||||
InterfaceType::Anyref => "anyref".into(),
|
||||
InterfaceType::I32 => "i32".into(),
|
||||
InterfaceType::I64 => "i64".into(),
|
||||
InterfaceType::S8 => "s8".to_string(),
|
||||
InterfaceType::S16 => "s16".to_string(),
|
||||
InterfaceType::S32 => "s32".to_string(),
|
||||
InterfaceType::S64 => "s64".to_string(),
|
||||
InterfaceType::U8 => "u8".to_string(),
|
||||
InterfaceType::U16 => "u16".to_string(),
|
||||
InterfaceType::U32 => "u32".to_string(),
|
||||
InterfaceType::U64 => "u64".to_string(),
|
||||
InterfaceType::F32 => "f32".to_string(),
|
||||
InterfaceType::F64 => "f64".to_string(),
|
||||
InterfaceType::String => "string".to_string(),
|
||||
InterfaceType::Anyref => "anyref".to_string(),
|
||||
InterfaceType::I32 => "i32".to_string(),
|
||||
InterfaceType::I64 => "i64".to_string(),
|
||||
InterfaceType::Record(record_type) => record_type.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for &RecordType {
|
||||
fn to_string(&self) -> String {
|
||||
format!(
|
||||
"record{fields}",
|
||||
fields = self
|
||||
.fields
|
||||
.iter()
|
||||
.fold(String::new(), |mut accumulator, interface_type| {
|
||||
accumulator.push(' ');
|
||||
accumulator.push_str(&format!("(field {})", &interface_type.to_string()));
|
||||
accumulator
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Encode an `Instruction` into a string.
|
||||
impl ToString for &Instruction {
|
||||
fn to_string(&self) -> String {
|
||||
@ -174,15 +191,9 @@ impl<'input> ToString for &Type {
|
||||
outputs = output_types_to_result(&outputs),
|
||||
),
|
||||
|
||||
Type::Record { fields } => format!(
|
||||
r#"(@interface type (record{fields}))"#,
|
||||
fields = fields
|
||||
.iter()
|
||||
.fold(String::new(), |mut accumulator, interface_type| {
|
||||
accumulator.push(' ');
|
||||
accumulator.push_str(&interface_type.to_string());
|
||||
accumulator
|
||||
}),
|
||||
Type::Record(record_type) => format!(
|
||||
r#"(@interface type ({record_type}))"#,
|
||||
record_type = record_type.to_string(),
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -354,10 +365,58 @@ mod tests {
|
||||
(&InterfaceType::Anyref).to_string(),
|
||||
(&InterfaceType::I32).to_string(),
|
||||
(&InterfaceType::I64).to_string(),
|
||||
(&InterfaceType::Record(RecordType {
|
||||
fields: vec![InterfaceType::String],
|
||||
}))
|
||||
.to_string(),
|
||||
];
|
||||
let outputs = vec![
|
||||
"s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64", "f32", "f64", "string", "anyref",
|
||||
"i32", "i64",
|
||||
"s8",
|
||||
"s16",
|
||||
"s32",
|
||||
"s64",
|
||||
"u8",
|
||||
"u16",
|
||||
"u32",
|
||||
"u64",
|
||||
"f32",
|
||||
"f64",
|
||||
"string",
|
||||
"anyref",
|
||||
"i32",
|
||||
"i64",
|
||||
"record (field string)",
|
||||
];
|
||||
|
||||
assert_eq!(inputs, outputs);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_record_type() {
|
||||
let inputs = vec![
|
||||
(&RecordType {
|
||||
fields: vec![InterfaceType::String],
|
||||
})
|
||||
.to_string(),
|
||||
(&RecordType {
|
||||
fields: vec![InterfaceType::String, InterfaceType::I32],
|
||||
})
|
||||
.to_string(),
|
||||
(&RecordType {
|
||||
fields: vec![
|
||||
InterfaceType::String,
|
||||
InterfaceType::Record(RecordType {
|
||||
fields: vec![InterfaceType::I32, InterfaceType::I32],
|
||||
}),
|
||||
InterfaceType::F64,
|
||||
],
|
||||
})
|
||||
.to_string(),
|
||||
];
|
||||
let outputs = vec![
|
||||
"record (field string)",
|
||||
"record (field string) (field i32)",
|
||||
"record (field string) (field record (field i32) (field i32)) (field f64)",
|
||||
];
|
||||
|
||||
assert_eq!(inputs, outputs);
|
||||
@ -473,9 +532,9 @@ mod tests {
|
||||
outputs: vec![],
|
||||
})
|
||||
.to_string(),
|
||||
(&Type::Record {
|
||||
(&Type::Record(RecordType {
|
||||
fields: vec![InterfaceType::String, InterfaceType::I32],
|
||||
})
|
||||
}))
|
||||
.to_string(),
|
||||
];
|
||||
let outputs = vec![
|
||||
@ -487,7 +546,7 @@ mod tests {
|
||||
r#"(@interface type (func
|
||||
(result i32)))"#,
|
||||
r#"(@interface type (func))"#,
|
||||
r#"(@interface type (record string i32))"#,
|
||||
r#"(@interface type (record (field string) (field i32)))"#,
|
||||
];
|
||||
|
||||
assert_eq!(inputs, outputs);
|
||||
|
@ -15,9 +15,9 @@ fn test_binary_encoding_decoding_roundtrip() {
|
||||
inputs: vec![InterfaceType::I32, InterfaceType::I32],
|
||||
outputs: vec![InterfaceType::S32],
|
||||
},
|
||||
Type::Record {
|
||||
Type::Record(RecordType {
|
||||
fields: vec![InterfaceType::String, InterfaceType::I32],
|
||||
},
|
||||
}),
|
||||
],
|
||||
imports: vec![Import {
|
||||
namespace: "a",
|
||||
|
Loading…
Reference in New Issue
Block a user