From 7ad156bd6a5364aae636bc59aa0577aaee2ab0f5 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 30 Mar 2020 08:32:31 +0200 Subject: [PATCH] feat(interface-types) Add the `Record` WIT value. --- src/interpreter/wasm/values.rs | 115 +++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 4 deletions(-) diff --git a/src/interpreter/wasm/values.rs b/src/interpreter/wasm/values.rs index 484fa1d..a2cb832 100644 --- a/src/interpreter/wasm/values.rs +++ b/src/interpreter/wasm/values.rs @@ -1,25 +1,54 @@ -#![allow(missing_docs)] +//! Defines WIT values and associated operations. -pub use crate::ast::InterfaceType; +pub use crate::ast::{InterfaceType, RecordType}; use crate::errors::WasmValueNativeCastError; use std::convert::TryFrom; +/// A WIT value. #[derive(Debug, Clone, PartialEq)] pub enum InterfaceValue { + /// A 8-bits signed integer. S8(i8), + + /// A 16-bits signed integer. S16(i16), + + /// A 32-bits signed integer. S32(i32), + + /// A 64-bits signed integer. S64(i64), + + /// A 8-bits unsigned integer. U8(u8), + + /// A 16-bits unsigned integer. U16(u16), + + /// A 32-bits unsigned integer. U32(u32), + + /// A 64-bits unsigned integer. U64(u64), + + /// A 32-bits float. F32(f32), + + /// A 64-bits float. F64(f64), + + /// A string. String(String), + //Anyref(?), + /// A 32-bits integer (as defined in WebAssembly core). I32(i32), + + /// A 64-bits integer (as defiend in WebAssembly core). I64(i64), + + /// A record. + Record(Vec), } impl From<&InterfaceValue> for InterfaceType { @@ -39,6 +68,12 @@ impl From<&InterfaceValue> for InterfaceType { //InterfaceValue::Anyref(_) => Self::Anyref, InterfaceValue::I32(_) => Self::I32, InterfaceValue::I64(_) => Self::I64, + InterfaceValue::Record(values) => Self::Record(RecordType { + fields: values + .iter() + .map(Into::into) + .collect::>(), + }), } } } @@ -49,7 +84,9 @@ impl Default for InterfaceValue { } } +/// Represents a native type supported by WIT. pub trait NativeType { + /// The associated interface type that maps to the native type. const INTERFACE_TYPE: InterfaceType; } @@ -83,6 +120,8 @@ macro_rules! native { native!(i8, S8); native!(i16, S16); +native!(i32, I32); +native!(i64, I64); native!(u8, U8); native!(u16, U16); native!(u32, U32); @@ -90,5 +129,73 @@ native!(u64, U64); native!(f32, F32); native!(f64, F64); native!(String, String); -native!(i32, I32); -native!(i64, I64); + +#[cfg(test)] +mod tests { + use super::*; + + macro_rules! value_to_type { + ($test_name:ident, $ty:ident, $value:expr) => { + #[test] + #[allow(non_snake_case)] + fn $test_name() { + assert_eq!( + InterfaceType::from(&InterfaceValue::$ty($value)), + InterfaceType::$ty + ); + } + }; + } + + value_to_type!(interface_type_from_interface_value__s8, S8, 42); + value_to_type!(interface_type_from_interface_value__s16, S16, 42); + value_to_type!(interface_type_from_interface_value__s32, S32, 42); + value_to_type!(interface_type_from_interface_value__s64, S64, 42); + value_to_type!(interface_type_from_interface_value__u8, U8, 42); + value_to_type!(interface_type_from_interface_value__u16, U16, 42); + value_to_type!(interface_type_from_interface_value__u32, U32, 42); + value_to_type!(interface_type_from_interface_value__u64, U64, 42); + value_to_type!(interface_type_from_interface_value__f32, F32, 42.); + value_to_type!(interface_type_from_interface_value__f64, F64, 42.); + value_to_type!( + interface_type_from_interface_value__string, + String, + "foo".to_string() + ); + value_to_type!(interface_type_from_interface_value__i32, I32, 42); + value_to_type!(interface_type_from_interface_value__i64, I64, 42); + + #[test] + #[allow(non_snake_case)] + fn interface_type_from_interface_value__record() { + assert_eq!( + InterfaceType::from(&InterfaceValue::Record(vec![ + InterfaceValue::I32(1), + InterfaceValue::S8(2) + ])), + InterfaceType::Record(RecordType { + fields: vec![InterfaceType::I32, InterfaceType::S8] + }) + ); + + assert_eq!( + InterfaceType::from(&InterfaceValue::Record(vec![ + InterfaceValue::I32(1), + InterfaceValue::Record(vec![ + InterfaceValue::String("a".to_string()), + InterfaceValue::F64(42.) + ]), + InterfaceValue::S8(2) + ])), + InterfaceType::Record(RecordType { + fields: vec![ + InterfaceType::I32, + InterfaceType::Record(RecordType { + fields: vec![InterfaceType::String, InterfaceType::F64] + }), + InterfaceType::S8 + ] + }) + ); + } +}