chore(interface-types) Reorganize the serde module.

This commit is contained in:
Ivan Enderlin 2020-03-31 08:02:46 +02:00
parent ee57b47770
commit 3655ef8bb7
4 changed files with 79 additions and 28 deletions

View File

@ -2,6 +2,6 @@
//! types, and traits —basically this is the part a runtime should //! types, and traits —basically this is the part a runtime should
//! take a look to use the `wasmer-interface-types` crate—. //! take a look to use the `wasmer-interface-types` crate—.
mod specific_values; mod serde;
pub mod structures; pub mod structures;
pub mod values; pub mod values;

View File

@ -1,6 +1,6 @@
//! Specific operations on records. //! Serde is not necessary to use WIT. It only provides a nicer API
//! for the end-user to rebuild its complex types from WIT values,
#![allow(missing_docs)] //! like `record`.
use crate::{ast::InterfaceType, interpreter::wasm::values::InterfaceValue}; use crate::{ast::InterfaceType, interpreter::wasm::values::InterfaceValue};
use serde::{ use serde::{
@ -13,6 +13,61 @@ use std::{
slice::Iter, slice::Iter,
}; };
/// Deserialize a set of `InterfaceValue`s to a type `T` that
/// implements `Deserialize`.
///
/// This is not a requirement to use WIT, but Serde provides an even
/// nicer API to the user to rebuild its complex types from WIT
/// values.
///
/// # Example
///
/// ```rust
/// use wasmer_interface_types::interpreter::wasm::values::{
/// InterfaceValue,
/// from_values,
/// };
/// use serde::Deserialize;
///
/// #[derive(Deserialize, Debug, PartialEq)]
/// struct S(i32, i64);
///
/// #[derive(Deserialize, Debug, PartialEq)]
/// struct T<'a> {
/// x: &'a str,
/// s: S,
/// y: f32,
/// };
///
/// let values = vec![
/// InterfaceValue::String("abc".to_string()),
/// InterfaceValue::Record(vec![InterfaceValue::I32(1), InterfaceValue::I64(2)]),
/// InterfaceValue::F32(3.),
/// ];
/// let t: T = from_values(&values).unwrap();
///
/// assert_eq!(
/// t,
/// T {
/// x: "abc",
/// s: S(1, 2),
/// y: 3.,
/// }
/// );
/// ```
pub fn from_values<'a, T>(values: &'a [InterfaceValue]) -> Result<T, Error>
where
T: Deserialize<'a>,
{
let mut deserializer = Deserializer::new(values);
let result = T::deserialize(&mut deserializer)?;
match deserializer.iterator.peek() {
None => Ok(result),
_ => Err(Error::InputNotEmpty),
}
}
/// Iterates over a vector of `InterfaceValues` but flatten all the /// Iterates over a vector of `InterfaceValues` but flatten all the
/// values for Serde. It means that the ideal representation for Serde /// values for Serde. It means that the ideal representation for Serde
/// regarding our implementation is to get all values flatten. So /// regarding our implementation is to get all values flatten. So
@ -60,6 +115,8 @@ impl<'a> Iterator for InterfaceValueIterator<'a> {
} }
} }
/// The deserializer. The iterator iterates over `InterfaceValue`s,
/// all flatten, see `InterfaceValueIterator`.
struct Deserializer<'de> { struct Deserializer<'de> {
iterator: Peekable<InterfaceValueIterator<'de>>, iterator: Peekable<InterfaceValueIterator<'de>>,
} }
@ -126,27 +183,25 @@ impl<'de> Deserializer<'de> {
next!(next_i64, I64, i64); next!(next_i64, I64, i64);
} }
pub fn from_values<'a, T>(values: &'a [InterfaceValue]) -> Result<T, Error> /// Represents an error while deserializing.
where
T: Deserialize<'a>,
{
let mut deserializer = Deserializer::new(values);
let result = T::deserialize(&mut deserializer)?;
match deserializer.iterator.peek() {
None => Ok(result),
_ => Err(Error::InputNotEmpty),
}
}
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum Error { pub enum Error {
/// The input isn't empty, i.e. some values aren't deserialized.
InputNotEmpty, InputNotEmpty,
/// The input is too short!
InputEmpty, InputEmpty,
/// The current value hasn't the expected type.
TypeMismatch { TypeMismatch {
/// The expected type.
expected_type: InterfaceType, expected_type: InterfaceType,
/// The received type.
received_type: InterfaceType, received_type: InterfaceType,
}, },
/// Arbitrary message.
Message(String), Message(String),
} }
@ -643,16 +698,13 @@ mod tests {
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn test_deserialize_value__record() { fn test_deserialize_value__record() {
#[derive(Deserialize, Debug, PartialEq)] #[derive(Deserialize, Debug, PartialEq)]
struct S { struct S(i32, i64);
x: i32,
y: i64,
};
#[derive(Deserialize, Debug, PartialEq)] #[derive(Deserialize, Debug, PartialEq)]
struct T { struct T {
a: String, x: String,
s: S, s: S,
b: f32, y: f32,
}; };
try_into!(T); try_into!(T);
@ -665,9 +717,9 @@ mod tests {
.try_into() .try_into()
.unwrap(); .unwrap();
let output = T { let output = T {
a: "abc".to_string(), x: "abc".to_string(),
s: S { x: 1, y: 2 }, s: S(1, 2),
b: 3., y: 3.,
}; };
assert_eq!(input, output); assert_eq!(input, output);

View File

@ -1 +0,0 @@
pub mod record;

View File

@ -2,7 +2,7 @@
pub use crate::ast::{InterfaceType, RecordType}; pub use crate::ast::{InterfaceType, RecordType};
use crate::errors::WasmValueNativeCastError; use crate::errors::WasmValueNativeCastError;
pub use crate::interpreter::wasm::specific_values::*; pub use crate::interpreter::wasm::serde::*;
use std::convert::TryFrom; use std::convert::TryFrom;
/// A WIT value. /// A WIT value.