From 858233a66d8c102a60279079d23725766f1a26cc Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 2 Apr 2020 16:46:23 +0200 Subject: [PATCH] =?UTF-8?q?chore(interface-types)=20Split=20the=20`serde`?= =?UTF-8?q?=20module=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … into `serde/ser.rs` and `serde/de.rs`. I like smaller files. --- .../wasm/{serde.rs => serde/de.rs} | 566 +---------------- src/interpreter/wasm/serde/mod.rs | 6 + src/interpreter/wasm/serde/ser.rs | 570 ++++++++++++++++++ src/interpreter/wasm/values.rs | 2 +- 4 files changed, 579 insertions(+), 565 deletions(-) rename src/interpreter/wasm/{serde.rs => serde/de.rs} (52%) create mode 100644 src/interpreter/wasm/serde/mod.rs create mode 100644 src/interpreter/wasm/serde/ser.rs diff --git a/src/interpreter/wasm/serde.rs b/src/interpreter/wasm/serde/de.rs similarity index 52% rename from src/interpreter/wasm/serde.rs rename to src/interpreter/wasm/serde/de.rs index 90dec2a..7ce955a 100644 --- a/src/interpreter/wasm/serde.rs +++ b/src/interpreter/wasm/serde/de.rs @@ -1,12 +1,10 @@ -//! Serde is not necessary to use WIT. It only provides a nicer API -//! for the end-user to send or receive its complex types to/from WIT -//! values, like `record` for instance. +//! Provides a deserializer from WIT values to Rust value. use crate::{ ast::InterfaceType, interpreter::wasm::values::{FlattenInterfaceValueIterator, InterfaceValue}, }; -use serde::{de, ser, Deserialize, Serialize}; +use serde::{de, Deserialize}; use std::{ fmt::{self, Display}, iter::Peekable, @@ -67,68 +65,6 @@ where } } -/// Serialize a type `T` that implements the `Serialize` trait to an -/// `InterfaceValue`. -/// -/// This is not a requirement to use WIT, but Serde provides an even -/// nicer API to the user to send its complex types to WIT. -/// -/// # Example -/// -/// ```rust -/// use wasmer_interface_types::interpreter::wasm::values::{ -/// InterfaceValue, -/// to_interface_value, -/// }; -/// use serde::Serialize; -/// -/// #[derive(Serialize)] -/// struct S(i32, i64); -/// -/// #[derive(Serialize)] -/// struct T { -/// x: String, -/// s: S, -/// y: f32, -/// }; -/// -/// let input = T { -/// x: "abc".to_string(), -/// s: S(1, 2), -/// y: 3., -/// }; -/// -/// assert_eq!( -/// to_interface_value(&input).unwrap(), -/// InterfaceValue::Record(vec![ -/// InterfaceValue::String("abc".to_string()), -/// InterfaceValue::Record(vec![InterfaceValue::I32(1), InterfaceValue::I64(2)]), -/// InterfaceValue::F32(3.), -/// ]), -/// ); -/// ``` -pub fn to_interface_value(value: &T) -> Result -where - T: Serialize, -{ - let mut serializer = Serializer::new(); - value.serialize(&mut serializer)?; - - if serializer.values.len() != 1 { - Err(SerializeError::TransformationNotFinished) - } else { - let mut first_values = serializer.values.pop().unwrap(); // this `unwrap` is safe because we are sure the length is 1. - - if first_values.len() != 1 { - Err(SerializeError::TransformationNotFinished) - } else { - let first_value = first_values.pop().unwrap(); // this `unwrap` is safe because we are sure the length is 1. - - Ok(first_value) - } - } -} - /// The deserializer. The iterator iterates over `InterfaceValue`s, /// all flatten, see `FlattenInterfaceValueIterator`. struct Deserializer<'de> { @@ -523,399 +459,6 @@ impl<'de, 'a> de::SeqAccess<'de> for Sequence<'a, 'de> { } } -/// The serializer. -struct Serializer { - values: Vec>, -} - -impl Serializer { - fn new() -> Self { - Self { - values: vec![vec![]], - } - } - - fn last(&mut self) -> &mut Vec { - let index = self.values.len() - 1; - - &mut self.values[index] - } - - fn push_with_capacity(&mut self, capacity: usize) { - self.values.push(Vec::with_capacity(capacity)); - } - - fn pop(&mut self) -> Result, SerializeError> { - if self.values.len() < 2 { - Err(SerializeError::InternalValuesCorrupted) - } else { - Ok(self.values.pop().unwrap()) // this `unwrap` is safe before `self.values` contains at least 2 items - } - } -} - -/// Represents an error while serializing. -#[derive(Clone, Debug, PartialEq)] -pub enum SerializeError { - /// The serialization still has pending values internally. - TransformationNotFinished, - - /// The internal values have been corrupted during the - /// serialization. - InternalValuesCorrupted, - - /// Arbitrary message. - Message(String), -} - -impl ser::Error for SerializeError { - fn custom(msg: T) -> Self { - Self::Message(msg.to_string()) - } -} - -impl Display for SerializeError { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::TransformationNotFinished => write!( - formatter, - "serialization still has pending values internally, something incorrect happened" - ), - Self::InternalValuesCorrupted => write!( - formatter, - "the internal values have been corrutped during the serialization" - ), - Self::Message(ref msg) => write!(formatter, "{}", msg), - } - } -} - -impl std::error::Error for SerializeError {} - -impl<'a> ser::Serializer for &'a mut Serializer { - type Ok = (); - type Error = SerializeError; - - type SerializeSeq = Self; - type SerializeTuple = Self; - type SerializeTupleStruct = Self; - type SerializeTupleVariant = Self; - type SerializeMap = Self; - type SerializeStruct = Self; - type SerializeStructVariant = Self; - - fn serialize_bool(self, _value: bool) -> Result { - unimplemented!("`bool` is not supported by WIT for the moment.") - } - - fn serialize_i8(self, value: i8) -> Result { - self.last().push(value.into()); - - Ok(()) - } - - fn serialize_i16(self, value: i16) -> Result { - self.last().push(value.into()); - - Ok(()) - } - - fn serialize_i32(self, value: i32) -> Result { - self.last().push(value.into()); - - Ok(()) - } - - fn serialize_i64(self, value: i64) -> Result { - self.last().push(value.into()); - - Ok(()) - } - - fn serialize_u8(self, value: u8) -> Result { - self.last().push(value.into()); - - Ok(()) - } - - fn serialize_u16(self, value: u16) -> Result { - self.last().push(value.into()); - - Ok(()) - } - - fn serialize_u32(self, value: u32) -> Result { - self.last().push(value.into()); - - Ok(()) - } - - fn serialize_u64(self, value: u64) -> Result { - self.last().push(value.into()); - - Ok(()) - } - - fn serialize_f32(self, value: f32) -> Result { - self.last().push(value.into()); - - Ok(()) - } - - fn serialize_f64(self, value: f64) -> Result { - self.last().push(value.into()); - - Ok(()) - } - - fn serialize_char(self, _value: char) -> Result { - todo!("`char` is not supported by WIT for the moment.") - } - - fn serialize_str(self, value: &str) -> Result { - self.last().push(value.to_owned().into()); - - Ok(()) - } - - fn serialize_bytes(self, _value: &[u8]) -> Result { - todo!("`bytes` is not supported by WIT for the moment.") - } - - fn serialize_none(self) -> Result { - self.serialize_unit() - } - - fn serialize_some(self, _value: &T) -> Result - where - T: ?Sized + Serialize, - { - todo!("`some` is not supported by WIT for the moment.") - } - - fn serialize_unit(self) -> Result { - todo!("`unit` is not supported by WIT for the moment.") - } - - fn serialize_unit_struct(self, _name: &'static str) -> Result { - todo!("`unit_struct` is not supported by WIT for the moment.") - } - - fn serialize_unit_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - ) -> Result { - todo!("`unit_variant` is not supported by WIT for the moment.") - } - - fn serialize_newtype_struct( - self, - _name: &'static str, - value: &T, - ) -> Result - where - T: ?Sized + Serialize, - { - value.serialize(self) - } - - fn serialize_newtype_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _value: &T, - ) -> Result - where - T: ?Sized + Serialize, - { - todo!("`newtype_variant` is not supported by WIT for the moment.") - } - - fn serialize_seq(self, _len: Option) -> Result { - todo!("`seq` is not supported by WIT for the moment.") - } - - fn serialize_tuple(self, _len: usize) -> Result { - todo!("`tuple` is not supported by WIT for the moment.") - } - - fn serialize_tuple_struct( - self, - _name: &'static str, - len: usize, - ) -> Result { - self.push_with_capacity(len); - - Ok(self) - } - - fn serialize_tuple_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - todo!("`tuple_variant` is not supported by WIT for the moment.") - } - - fn serialize_map(self, _len: Option) -> Result { - todo!("`map` is not supported by WIT for the moment.") - } - - fn serialize_struct( - self, - _name: &'static str, - len: usize, - ) -> Result { - self.push_with_capacity(len); - - Ok(self) - } - - fn serialize_struct_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - todo!("`struct_variant` is not supported by WIT for the moment.") - } -} - -impl<'a> ser::SerializeSeq for &'a mut Serializer { - type Ok = (); - type Error = SerializeError; - - fn serialize_element(&mut self, _value: &T) -> Result - where - T: ?Sized + Serialize, - { - unimplemented!() - } - - fn end(self) -> Result { - unimplemented!() - } -} - -impl<'a> ser::SerializeTuple for &'a mut Serializer { - type Ok = (); - type Error = SerializeError; - - fn serialize_element(&mut self, _value: &T) -> Result - where - T: ?Sized + Serialize, - { - unimplemented!() - } - - fn end(self) -> Result { - unimplemented!() - } -} - -impl<'a> ser::SerializeTupleStruct for &'a mut Serializer { - type Ok = (); - type Error = SerializeError; - - fn serialize_field(&mut self, value: &T) -> Result - where - T: ?Sized + Serialize, - { - value.serialize(&mut **self) - } - - fn end(self) -> Result { - let record = InterfaceValue::Record(self.pop()?); - self.last().push(record); - - Ok(()) - } -} - -impl<'a> ser::SerializeTupleVariant for &'a mut Serializer { - type Ok = (); - type Error = SerializeError; - - fn serialize_field(&mut self, _value: &T) -> Result - where - T: ?Sized + Serialize, - { - unimplemented!() - } - - fn end(self) -> Result { - unimplemented!() - } -} - -impl<'a> ser::SerializeMap for &'a mut Serializer { - type Ok = (); - type Error = SerializeError; - - fn serialize_key(&mut self, _key: &T) -> Result - where - T: ?Sized + Serialize, - { - unimplemented!() - } - - fn serialize_value(&mut self, _value: &T) -> Result - where - T: ?Sized + Serialize, - { - unimplemented!() - } - - fn end(self) -> Result { - unimplemented!() - } -} - -impl<'a> ser::SerializeStruct for &'a mut Serializer { - type Ok = (); - type Error = SerializeError; - - fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result - where - T: ?Sized + Serialize, - { - value.serialize(&mut **self) - } - - fn end(self) -> Result { - let record = InterfaceValue::Record(self.pop()?); - self.last().push(record); - - Ok(()) - } -} - -impl<'a> ser::SerializeStructVariant for &'a mut Serializer { - type Ok = (); - type Error = SerializeError; - - fn serialize_field( - &mut self, - _key: &'static str, - _value: &T, - ) -> Result - where - T: ?Sized + Serialize, - { - unimplemented!() - } - - fn end(self) -> Result { - unimplemented!() - } -} - #[cfg(test)] mod tests { use super::*; @@ -1044,109 +587,4 @@ mod tests { assert_eq!(from_interface_values::(&input).unwrap(), output); } - - macro_rules! serialize_value { - ($test_name:ident, $ty:ident, $variant:ident, $value:expr) => { - #[test] - #[allow(non_snake_case)] - fn $test_name() { - let input: $ty = $value; - let output = InterfaceValue::$variant($value); - - assert_eq!(to_interface_value(&input).unwrap(), output); - } - }; - } - - serialize_value!(test_serialize_value__s8, i8, S8, 42); - serialize_value!(test_serialize_value__s16, i16, S16, 42); - serialize_value!(test_serialize_value__i32, i32, I32, 42); - serialize_value!(test_serialize_value__i64, i64, I64, 42); - serialize_value!(test_serialize_value__u8, u8, U8, 42); - serialize_value!(test_serialize_value__u16, u16, U16, 42); - serialize_value!(test_serialize_value__u32, u32, U32, 42); - serialize_value!(test_serialize_value__u64, u64, U64, 42); - serialize_value!(test_serialize_value__f32, f32, F32, 42.); - serialize_value!(test_serialize_value__f64, f32, F32, 42.); - serialize_value!( - test_serialize_value__string, - String, - String, - "foo".to_string() - ); - - #[test] - #[allow(non_snake_case)] - fn test_serialize_value__newtype_struct() { - #[derive(Serialize)] - struct S(i8); - - let input = S(42); - let output = InterfaceValue::S8(42); - - assert_eq!(to_interface_value(&input).unwrap(), output); - } - - #[test] - #[allow(non_snake_case)] - fn test_serialize_value__tuple_struct() { - #[derive(Serialize)] - struct S(i8, f32); - - let input = S(7, 42.); - let output = InterfaceValue::Record(vec![InterfaceValue::S8(7), InterfaceValue::F32(42.)]); - - assert_eq!(to_interface_value(&input).unwrap(), output); - } - - #[test] - #[allow(non_snake_case)] - fn test_serialize_value__struct() { - #[derive(Serialize)] - struct S { - x: i8, - y: f32, - } - - let input = S { x: 7, y: 42. }; - let output = InterfaceValue::Record(vec![InterfaceValue::S8(7), InterfaceValue::F32(42.)]); - - assert_eq!(to_interface_value(&input).unwrap(), output); - } - - #[test] - #[allow(non_snake_case)] - fn test_serialize_value__struct_nested() { - #[derive(Serialize)] - struct Point { - x: i32, - y: i32, - z: i32, - } - - #[derive(Serialize)] - struct Line { - p1: Point, - p2: Point, - } - - let input = Line { - p1: Point { x: 1, y: 2, z: 3 }, - p2: Point { x: 4, y: 5, z: 6 }, - }; - let output = InterfaceValue::Record(vec![ - InterfaceValue::Record(vec![ - InterfaceValue::I32(1), - InterfaceValue::I32(2), - InterfaceValue::I32(3), - ]), - InterfaceValue::Record(vec![ - InterfaceValue::I32(4), - InterfaceValue::I32(5), - InterfaceValue::I32(6), - ]), - ]); - - assert_eq!(to_interface_value(&input).unwrap(), output); - } } diff --git a/src/interpreter/wasm/serde/mod.rs b/src/interpreter/wasm/serde/mod.rs new file mode 100644 index 0000000..6cc35e2 --- /dev/null +++ b/src/interpreter/wasm/serde/mod.rs @@ -0,0 +1,6 @@ +//! Serde is not necessary to use WIT. It only provides a nicer API +//! for the end-user to send or receive its complex types to/from WIT +//! values, like `record` for instance. + +pub(crate) mod de; +pub(crate) mod ser; diff --git a/src/interpreter/wasm/serde/ser.rs b/src/interpreter/wasm/serde/ser.rs new file mode 100644 index 0000000..0fdd923 --- /dev/null +++ b/src/interpreter/wasm/serde/ser.rs @@ -0,0 +1,570 @@ +//! Provides a serializer from Rust value to WIT values. + +use crate::interpreter::wasm::values::InterfaceValue; +use serde::{ser, Serialize}; +use std::fmt::{self, Display}; + +/// Serialize a type `T` that implements the `Serialize` trait to an +/// `InterfaceValue`. +/// +/// This is not a requirement to use WIT, but Serde provides an even +/// nicer API to the user to send its complex types to WIT. +/// +/// # Example +/// +/// ```rust +/// use wasmer_interface_types::interpreter::wasm::values::{ +/// InterfaceValue, +/// to_interface_value, +/// }; +/// use serde::Serialize; +/// +/// #[derive(Serialize)] +/// struct S(i32, i64); +/// +/// #[derive(Serialize)] +/// struct T { +/// x: String, +/// s: S, +/// y: f32, +/// }; +/// +/// let input = T { +/// x: "abc".to_string(), +/// s: S(1, 2), +/// y: 3., +/// }; +/// +/// assert_eq!( +/// to_interface_value(&input).unwrap(), +/// InterfaceValue::Record(vec![ +/// InterfaceValue::String("abc".to_string()), +/// InterfaceValue::Record(vec![InterfaceValue::I32(1), InterfaceValue::I64(2)]), +/// InterfaceValue::F32(3.), +/// ]), +/// ); +/// ``` +pub fn to_interface_value(value: &T) -> Result +where + T: Serialize, +{ + let mut serializer = Serializer::new(); + value.serialize(&mut serializer)?; + + if serializer.values.len() != 1 { + Err(SerializeError::TransformationNotFinished) + } else { + let mut first_values = serializer.values.pop().unwrap(); // this `unwrap` is safe because we are sure the length is 1. + + if first_values.len() != 1 { + Err(SerializeError::TransformationNotFinished) + } else { + let first_value = first_values.pop().unwrap(); // this `unwrap` is safe because we are sure the length is 1. + + Ok(first_value) + } + } +} + +/// The serializer. +struct Serializer { + values: Vec>, +} + +impl Serializer { + fn new() -> Self { + Self { + values: vec![vec![]], + } + } + + fn last(&mut self) -> &mut Vec { + let index = self.values.len() - 1; + + &mut self.values[index] + } + + fn push_with_capacity(&mut self, capacity: usize) { + self.values.push(Vec::with_capacity(capacity)); + } + + fn pop(&mut self) -> Result, SerializeError> { + if self.values.len() < 2 { + Err(SerializeError::InternalValuesCorrupted) + } else { + Ok(self.values.pop().unwrap()) // this `unwrap` is safe before `self.values` contains at least 2 items + } + } +} + +/// Represents an error while serializing. +#[derive(Clone, Debug, PartialEq)] +pub enum SerializeError { + /// The serialization still has pending values internally. + TransformationNotFinished, + + /// The internal values have been corrupted during the + /// serialization. + InternalValuesCorrupted, + + /// Arbitrary message. + Message(String), +} + +impl ser::Error for SerializeError { + fn custom(msg: T) -> Self { + Self::Message(msg.to_string()) + } +} + +impl Display for SerializeError { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::TransformationNotFinished => write!( + formatter, + "serialization still has pending values internally, something incorrect happened" + ), + Self::InternalValuesCorrupted => write!( + formatter, + "the internal values have been corrutped during the serialization" + ), + Self::Message(ref msg) => write!(formatter, "{}", msg), + } + } +} + +impl std::error::Error for SerializeError {} + +impl<'a> ser::Serializer for &'a mut Serializer { + type Ok = (); + type Error = SerializeError; + + type SerializeSeq = Self; + type SerializeTuple = Self; + type SerializeTupleStruct = Self; + type SerializeTupleVariant = Self; + type SerializeMap = Self; + type SerializeStruct = Self; + type SerializeStructVariant = Self; + + fn serialize_bool(self, _value: bool) -> Result { + unimplemented!("`bool` is not supported by WIT for the moment.") + } + + fn serialize_i8(self, value: i8) -> Result { + self.last().push(value.into()); + + Ok(()) + } + + fn serialize_i16(self, value: i16) -> Result { + self.last().push(value.into()); + + Ok(()) + } + + fn serialize_i32(self, value: i32) -> Result { + self.last().push(value.into()); + + Ok(()) + } + + fn serialize_i64(self, value: i64) -> Result { + self.last().push(value.into()); + + Ok(()) + } + + fn serialize_u8(self, value: u8) -> Result { + self.last().push(value.into()); + + Ok(()) + } + + fn serialize_u16(self, value: u16) -> Result { + self.last().push(value.into()); + + Ok(()) + } + + fn serialize_u32(self, value: u32) -> Result { + self.last().push(value.into()); + + Ok(()) + } + + fn serialize_u64(self, value: u64) -> Result { + self.last().push(value.into()); + + Ok(()) + } + + fn serialize_f32(self, value: f32) -> Result { + self.last().push(value.into()); + + Ok(()) + } + + fn serialize_f64(self, value: f64) -> Result { + self.last().push(value.into()); + + Ok(()) + } + + fn serialize_char(self, _value: char) -> Result { + todo!("`char` is not supported by WIT for the moment.") + } + + fn serialize_str(self, value: &str) -> Result { + self.last().push(value.to_owned().into()); + + Ok(()) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result { + todo!("`bytes` is not supported by WIT for the moment.") + } + + fn serialize_none(self) -> Result { + self.serialize_unit() + } + + fn serialize_some(self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + todo!("`some` is not supported by WIT for the moment.") + } + + fn serialize_unit(self) -> Result { + todo!("`unit` is not supported by WIT for the moment.") + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + todo!("`unit_struct` is not supported by WIT for the moment.") + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result { + todo!("`unit_variant` is not supported by WIT for the moment.") + } + + fn serialize_newtype_struct( + self, + _name: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + todo!("`newtype_variant` is not supported by WIT for the moment.") + } + + fn serialize_seq(self, _len: Option) -> Result { + todo!("`seq` is not supported by WIT for the moment.") + } + + fn serialize_tuple(self, _len: usize) -> Result { + todo!("`tuple` is not supported by WIT for the moment.") + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.push_with_capacity(len); + + Ok(self) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + todo!("`tuple_variant` is not supported by WIT for the moment.") + } + + fn serialize_map(self, _len: Option) -> Result { + todo!("`map` is not supported by WIT for the moment.") + } + + fn serialize_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.push_with_capacity(len); + + Ok(self) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + todo!("`struct_variant` is not supported by WIT for the moment.") + } +} + +impl<'a> ser::SerializeSeq for &'a mut Serializer { + type Ok = (); + type Error = SerializeError; + + fn serialize_element(&mut self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + unimplemented!() + } + + fn end(self) -> Result { + unimplemented!() + } +} + +impl<'a> ser::SerializeTuple for &'a mut Serializer { + type Ok = (); + type Error = SerializeError; + + fn serialize_element(&mut self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + unimplemented!() + } + + fn end(self) -> Result { + unimplemented!() + } +} + +impl<'a> ser::SerializeTupleStruct for &'a mut Serializer { + type Ok = (); + type Error = SerializeError; + + fn serialize_field(&mut self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(&mut **self) + } + + fn end(self) -> Result { + let record = InterfaceValue::Record(self.pop()?); + self.last().push(record); + + Ok(()) + } +} + +impl<'a> ser::SerializeTupleVariant for &'a mut Serializer { + type Ok = (); + type Error = SerializeError; + + fn serialize_field(&mut self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + unimplemented!() + } + + fn end(self) -> Result { + unimplemented!() + } +} + +impl<'a> ser::SerializeMap for &'a mut Serializer { + type Ok = (); + type Error = SerializeError; + + fn serialize_key(&mut self, _key: &T) -> Result + where + T: ?Sized + Serialize, + { + unimplemented!() + } + + fn serialize_value(&mut self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + unimplemented!() + } + + fn end(self) -> Result { + unimplemented!() + } +} + +impl<'a> ser::SerializeStruct for &'a mut Serializer { + type Ok = (); + type Error = SerializeError; + + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(&mut **self) + } + + fn end(self) -> Result { + let record = InterfaceValue::Record(self.pop()?); + self.last().push(record); + + Ok(()) + } +} + +impl<'a> ser::SerializeStructVariant for &'a mut Serializer { + type Ok = (); + type Error = SerializeError; + + fn serialize_field( + &mut self, + _key: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + unimplemented!() + } + + fn end(self) -> Result { + unimplemented!() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + macro_rules! serialize_value { + ($test_name:ident, $ty:ident, $variant:ident, $value:expr) => { + #[test] + #[allow(non_snake_case)] + fn $test_name() { + let input: $ty = $value; + let output = InterfaceValue::$variant($value); + + assert_eq!(to_interface_value(&input).unwrap(), output); + } + }; + } + + serialize_value!(test_serialize_value__s8, i8, S8, 42); + serialize_value!(test_serialize_value__s16, i16, S16, 42); + serialize_value!(test_serialize_value__i32, i32, I32, 42); + serialize_value!(test_serialize_value__i64, i64, I64, 42); + serialize_value!(test_serialize_value__u8, u8, U8, 42); + serialize_value!(test_serialize_value__u16, u16, U16, 42); + serialize_value!(test_serialize_value__u32, u32, U32, 42); + serialize_value!(test_serialize_value__u64, u64, U64, 42); + serialize_value!(test_serialize_value__f32, f32, F32, 42.); + serialize_value!(test_serialize_value__f64, f32, F32, 42.); + serialize_value!( + test_serialize_value__string, + String, + String, + "foo".to_string() + ); + + #[test] + #[allow(non_snake_case)] + fn test_serialize_value__newtype_struct() { + #[derive(Serialize)] + struct S(i8); + + let input = S(42); + let output = InterfaceValue::S8(42); + + assert_eq!(to_interface_value(&input).unwrap(), output); + } + + #[test] + #[allow(non_snake_case)] + fn test_serialize_value__tuple_struct() { + #[derive(Serialize)] + struct S(i8, f32); + + let input = S(7, 42.); + let output = InterfaceValue::Record(vec![InterfaceValue::S8(7), InterfaceValue::F32(42.)]); + + assert_eq!(to_interface_value(&input).unwrap(), output); + } + + #[test] + #[allow(non_snake_case)] + fn test_serialize_value__struct() { + #[derive(Serialize)] + struct S { + x: i8, + y: f32, + } + + let input = S { x: 7, y: 42. }; + let output = InterfaceValue::Record(vec![InterfaceValue::S8(7), InterfaceValue::F32(42.)]); + + assert_eq!(to_interface_value(&input).unwrap(), output); + } + + #[test] + #[allow(non_snake_case)] + fn test_serialize_value__struct_nested() { + #[derive(Serialize)] + struct Point { + x: i32, + y: i32, + z: i32, + } + + #[derive(Serialize)] + struct Line { + p1: Point, + p2: Point, + } + + let input = Line { + p1: Point { x: 1, y: 2, z: 3 }, + p2: Point { x: 4, y: 5, z: 6 }, + }; + let output = InterfaceValue::Record(vec![ + InterfaceValue::Record(vec![ + InterfaceValue::I32(1), + InterfaceValue::I32(2), + InterfaceValue::I32(3), + ]), + InterfaceValue::Record(vec![ + InterfaceValue::I32(4), + InterfaceValue::I32(5), + InterfaceValue::I32(6), + ]), + ]); + + assert_eq!(to_interface_value(&input).unwrap(), output); + } +} diff --git a/src/interpreter/wasm/values.rs b/src/interpreter/wasm/values.rs index 1ba005d..44df1d5 100644 --- a/src/interpreter/wasm/values.rs +++ b/src/interpreter/wasm/values.rs @@ -5,7 +5,7 @@ use crate::errors::WasmValueNativeCastError; use std::{convert::TryFrom, slice::Iter}; #[cfg(feature = "serde")] -pub use crate::interpreter::wasm::serde::*; +pub use crate::interpreter::wasm::serde::{de::*, ser::*}; /// A WIT value. #[derive(Debug, Clone, PartialEq)]