diff --git a/src/interpreter/wasm/serde.rs b/src/interpreter/wasm/serde.rs index 64324fb..7064a8f 100644 --- a/src/interpreter/wasm/serde.rs +++ b/src/interpreter/wasm/serde.rs @@ -2,7 +2,10 @@ //! for the end-user to rebuild its complex types from WIT values, //! like `record`. -use crate::{ast::InterfaceType, interpreter::wasm::values::InterfaceValue}; +use crate::{ + ast::InterfaceType, + interpreter::wasm::values::{FlattenInterfaceValueIterator, InterfaceValue}, +}; use serde::{ de::{self, DeserializeSeed, SeqAccess, Visitor}, Deserialize, @@ -10,7 +13,6 @@ use serde::{ use std::{ fmt::{self, Display}, iter::Peekable, - slice::Iter, }; /// Deserialize a set of `InterfaceValue`s to a type `T` that @@ -68,63 +70,16 @@ where } } -/// Iterates over a vector of `InterfaceValues` but flatten all the -/// values for Serde. It means that the ideal representation for Serde -/// regarding our implementation is to get all values flatten. So -/// `I32(1), Record([I32(2), I32(3)]), I32(4)` must be iterated like -/// `I32(1), I32(2), I32(3), I32(4)`. -struct InterfaceValueIterator<'a> { - iterators: Vec>, -} - -impl<'a> InterfaceValueIterator<'a> { - fn new(values: &'a [InterfaceValue]) -> Self { - Self { - iterators: vec![values.iter()], - } - } -} - -impl<'a> Iterator for InterfaceValueIterator<'a> { - type Item = &'a InterfaceValue; - - fn next(&mut self) -> Option { - if self.iterators.is_empty() { - return None; - } - - let index = self.iterators.len() - 1; - - match self.iterators[index].next() { - // End of the current iterator, go back to the previous - // one. - None => { - self.iterators.pop(); - self.next() - } - - // Recursively iterate over the record. - Some(InterfaceValue::Record(values)) => { - self.iterators.push(values.iter()); - self.next() - } - - // A regular item. - e @ Some(_) => e, - } - } -} - /// The deserializer. The iterator iterates over `InterfaceValue`s, -/// all flatten, see `InterfaceValueIterator`. +/// all flatten, see `FlattenInterfaceValueIterator`. struct Deserializer<'de> { - iterator: Peekable>, + iterator: Peekable>, } impl<'de> Deserializer<'de> { pub fn new(input: &'de [InterfaceValue]) -> Deserializer<'de> { Deserializer { - iterator: InterfaceValueIterator::new(input).peekable(), + iterator: FlattenInterfaceValueIterator::new(input).peekable(), } } } diff --git a/src/interpreter/wasm/values.rs b/src/interpreter/wasm/values.rs index 5cd2ea1..472be98 100644 --- a/src/interpreter/wasm/values.rs +++ b/src/interpreter/wasm/values.rs @@ -3,7 +3,7 @@ pub use crate::ast::{InterfaceType, RecordType}; use crate::errors::WasmValueNativeCastError; pub use crate::interpreter::wasm::serde::*; -use std::convert::TryFrom; +use std::{convert::TryFrom, slice::Iter}; /// A WIT value. #[derive(Debug, Clone, PartialEq)] @@ -128,6 +128,51 @@ native!(f32, F32); native!(f64, F64); native!(String, String); +/// Iterates over a vector of `InterfaceValues` but flatten all the +/// values. So `I32(1), Record([I32(2), I32(3)]), I32(4)` will be +/// iterated like `I32(1), I32(2), I32(3), I32(4)`. +pub(crate) struct FlattenInterfaceValueIterator<'a> { + iterators: Vec>, +} + +impl<'a> FlattenInterfaceValueIterator<'a> { + pub(crate) fn new(values: &'a [InterfaceValue]) -> Self { + Self { + iterators: vec![values.iter()], + } + } +} + +impl<'a> Iterator for FlattenInterfaceValueIterator<'a> { + type Item = &'a InterfaceValue; + + fn next(&mut self) -> Option { + if self.iterators.is_empty() { + return None; + } + + let index = self.iterators.len() - 1; + + match self.iterators[index].next() { + // End of the current iterator, go back to the previous + // one. + None => { + self.iterators.pop(); + self.next() + } + + // Recursively iterate over the record. + Some(InterfaceValue::Record(values)) => { + self.iterators.push(values.iter()); + self.next() + } + + // A regular item. + e @ Some(_) => e, + } + } +} + #[cfg(test)] mod tests { use super::*;