diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2022-10-10 23:50:37 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2022-10-10 23:50:37 -0300 |
commit | dcf5620842edb8a4632cde794c8e511e075d3662 (patch) | |
tree | f96498f2a455ce092a32b83c00e999102b5edd31 /src/vm/de.rs | |
parent | f0e944696144016ca59aaed02381f7ea9d1ef848 (diff) |
Initial implementation of Packer::deserialize
Diffstat (limited to 'src/vm/de.rs')
-rw-r--r-- | src/vm/de.rs | 259 |
1 files changed, 149 insertions, 110 deletions
diff --git a/src/vm/de.rs b/src/vm/de.rs index 2282484..640b1aa 100644 --- a/src/vm/de.rs +++ b/src/vm/de.rs @@ -10,11 +10,13 @@ use indexmap::IndexMap; use serde::Serialize; use serde::de::Error as _; +use serde::de::IntoDeserializer as _; use smallvec::SmallVec; use these::These; +use super::Frame; use super::Interpreter; use super::Pack; use super::PatternConstants; @@ -33,56 +35,63 @@ pub(crate) struct Packer<'pat, 'state, O: Serialize> { call_limit: usize, /// Whether we're collecting values. collecting: bool, - /// Instructions currently being processed. - ops: SmallVec<[InstructionReg<'pat>; 1]>, } -/// Instruction currently being processed. -struct InstructionReg<'pat> { - /// The (current) program sequence. - instructions: &'pat [PatternElement], - /// Whether this instruction is required to match. - required: bool, +struct FramesMut<'packer, 'pat> { + frames: std::cell::RefMut<'packer, Vec<Frame<'pat>>>, +} + +struct Frames<'packer, 'pat> { + frames: std::cell::Ref<'packer, Vec<Frame<'pat>>>, +} + +impl<'packer, 'pat> FramesMut<'packer, 'pat> { + fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item=&'a mut Frame<'pat>> where 'packer: 'a { + self.frames.iter_mut() + } + + fn iter_active_mut<'a>(&'a mut self) -> impl Iterator<Item=&'a mut Frame<'pat>> where 'packer: 'a { + self.iter_mut().filter(|frame| { + frame.matches + }) + } +} + +impl<'packer, 'pat> Frames<'packer, 'pat> { + fn iter<'a>(&'a self) -> impl Iterator<Item=&'a Frame<'pat>> where 'packer: 'a { + self.frames.iter() + } + + fn iter_active<'a>(&'a self) -> impl Iterator<Item=&'a Frame<'pat>> where 'packer: 'a { + self.iter().filter(|frame| { + frame.matches + }) + } } impl<'pat, 'state, 'de, O: Serialize> Packer<'pat, 'state, O> { + /// Creates a new Packer. pub(crate) fn new( interp: Interpreter<'pat, 'state, O>, call_limit: usize, ) -> Self { - let ops = SmallVec::from_buf([ - InstructionReg { - instructions: &interp.pat.protos.last().unwrap()[..], - required: true, - } - ]); Self { interp: interp, call_limit: call_limit, collecting: false, - ops: ops, } } - /// Extracts the name for this element. - fn get_name(&self) -> SmallVec<[&'pat str; 1]> { - let mut name = SmallVec::<[&'pat str; 1]>::new(); - for reg in &self.ops { - match reg.instructions.first() { - | Some(PatternElement::Tag { name_and_value, .. }) - | Some(PatternElement::Value { name_and_value }) - => { - if let Some(name_key) = name_and_value.here() { - name.push(&self.interp.pat.strings[name_key]); - } - }, - None => { - // FIXME is this correct? - }, - _ => unreachable!(), - } + fn frames_mut(&mut self) -> FramesMut<'_, 'pat> { + FramesMut { + frames: self.interp.frames.borrow_mut(), + } + } + + fn frames(&mut self) -> Frames<'_, 'pat> { + Frames { + frames: self.interp.frames.borrow(), } - name } } @@ -118,67 +127,85 @@ where where D: serde::Deserializer<'de> { - match &*self.ops { - [] => unreachable!(), - [InstructionReg { - instructions: [], - .. - }] => { - // FIXME is this correct? - deserializer.deserialize_ignored_any(self) + self.frames_mut().iter_mut().for_each(|frame| { + if !frame.next() { + frame.matches = false; + } + }); + let pat = self.interp.pat; + let target_type = self.frames().iter_active().fold( + Type::IgnoredAny, + |target_type, frame| { + match (target_type, frame.get_type(pat)) { + (Type::IgnoredAny, Some((ty, _))) => ty, + (ty, Some((Type::IgnoredAny, _))) => ty, + (Type::String, Some((Type::Str, _))) => { + Type::String + }, + (Type::Str, Some((Type::String, _))) => { + Type::String + }, + (Type::Bytes, Some((Type::ByteBuf, _))) => { + Type::ByteBuf + }, + (Type::ByteBuf, Some((Type::Bytes, _))) => { + Type::ByteBuf + }, + (left, Some((right, _))) if left == right => { + left + }, + _ => Type::Any, + } + }, + ); + match target_type { + Type::Any => deserializer.deserialize_any(self), + Type::IgnoredAny => deserializer.deserialize_ignored_any(self), + Type::Bool => deserializer.deserialize_bool(self), + Type::I8 => deserializer.deserialize_i8(self), + Type::I16 => deserializer.deserialize_i16(self), + Type::I32 => deserializer.deserialize_i32(self), + Type::I64 => deserializer.deserialize_i64(self), + Type::I128 => deserializer.deserialize_i128(self), + Type::U8 => deserializer.deserialize_u8(self), + Type::U16 => deserializer.deserialize_u16(self), + Type::U32 => deserializer.deserialize_u32(self), + Type::U64 => deserializer.deserialize_u64(self), + Type::U128 => deserializer.deserialize_u128(self), + Type::F32 => deserializer.deserialize_f32(self), + Type::F64 => deserializer.deserialize_f64(self), + Type::Char => deserializer.deserialize_char(self), + Type::Str if !self.collecting => { + deserializer.deserialize_str(self) + }, + Type::Str | Type::String => deserializer.deserialize_string(self), + Type::Bytes if !self.collecting => { + deserializer.deserialize_bytes(self) + }, + Type::Bytes | Type::ByteBuf => { + deserializer.deserialize_byte_buf(self) + }, + Type::Option => deserializer.deserialize_option(self), + Type::Unit => deserializer.deserialize_unit(self), + Type::Seq => deserializer.deserialize_seq(self), + Type::Map => deserializer.deserialize_map(self), + Type::Identifier => deserializer.deserialize_identifier(self), + Type::Tuple(len) => deserializer.deserialize_tuple(len, self), + Type::UnitStruct(name) => { + deserializer.deserialize_unit_struct(name, self) + }, + Type::NewtypeStruct(name) => { + deserializer.deserialize_newtype_struct(name, self) }, - [InstructionReg { - instructions: [ins, ..], - .. - }] => match ins { - | PatternElement::Tag { name_and_value, .. } - | PatternElement::Value { name_and_value } - => { - match name_and_value.there() { - | Some(Value::String { .. }) - | Some(Value::Regex { .. }) => { - if name_and_value.is_here() { - deserializer.deserialize_string(self) - } else { - deserializer.deserialize_str(self) - } - }, - Some(Value::Type { ty, .. }) => match ty { - Type::Any => deserializer.deserialize_any(self), - Type::IgnoredAny => { - deserializer.deserialize_ignored_any(self) - }, - Type::Bool => deserializer.deserialize_bool(self), - Type::I8 => deserializer.deserialize_i8(self), - Type::I16 => deserializer.deserialize_i16(self), - Type::I32 => deserializer.deserialize_i32(self), - Type::I64 => deserializer.deserialize_i64(self), - Type::I128 => deserializer.deserialize_i128(self), - Type::U8 => deserializer.deserialize_u8(self), - Type::U16 => deserializer.deserialize_u16(self), - Type::U32 => deserializer.deserialize_u32(self), - Type::U64 => deserializer.deserialize_u64(self), - Type::U128 => deserializer.deserialize_u128(self), - Type::F32 => deserializer.deserialize_f32(self), - Type::F64 => deserializer.deserialize_f64(self), - Type::Char => deserializer.deserialize_char(self), - Type::Str => deserializer.deserialize_str(self), - Type::String => deserializer.deserialize_string(self), - Type::Bytes => deserializer.deserialize_bytes(self), - Type::ByteBuf => { - deserializer.deserialize_byte_buf(self) - }, - Type::Option => deserializer.deserialize_option(self), - Type::Unit => deserializer.deserialize_unit(self), - Type::Seq => deserializer.deserialize_seq(self), - Type::Map => deserializer.deserialize_map(self), - }, - None => todo!(), - } - }, - _ => todo!(), + Type::TupleStruct { name, len } => { + deserializer.deserialize_tuple_struct(name, len, self) + }, + Type::Struct { name, fields } => { + deserializer.deserialize_struct(name, fields, self) + }, + Type::Enum { name, variants } => { + deserializer.deserialize_enum(name, variants, self) }, - _ => todo!(), } } } @@ -186,21 +213,25 @@ where /// visit method generator for simple values (primitives). macro_rules! vs { ($visit:ident $obj:ident $t:ty) => { - fn $visit<E>(self, v: $t) -> Result<Self::Value, E> + fn $visit<E>(mut self, v: $t) -> Result<Self::Value, E> where E: serde::de::Error, { - // FIXME subtrees + // FIXME filtering/errors + let pat = self.interp.pat; let mut obj = None; - let mut pack = Pack::default(); if self.collecting { obj = Some(SerdeObject::$obj(v)); } - let mut map = IndexMap::new(); - for name in self.get_name() { - map.insert(name, (Default::default(), SerdeObject::$obj(v))); - } - pack.subpacks.push(map); + let mut pack = Pack::default(); + self.frames_mut().iter_active_mut().try_for_each(|frame| { + let mut map = IndexMap::new(); + if let Some(name) = frame.get_name(pat) { + map.insert(name, (Pack::default(), SerdeObject::$obj(v))); + } + pack.subpacks.push(map); + Ok(()) + })?; Ok((pack, obj)) } } @@ -322,9 +353,9 @@ where obj = Some(SerdeObject::Unit); } let mut map = IndexMap::new(); - for name in self.get_name() { - map.insert(name, (Default::default(), SerdeObject::Unit)); - } + //for name in self.get_name() { + // map.insert(name, (Default::default(), SerdeObject::Unit)); + //} pack.subpacks.push(map); Ok((pack, obj)) } @@ -473,12 +504,14 @@ where SerdeObject::Str(Cow::Borrowed(x)) => v.visit_borrowed_str(x), SerdeObject::Bytes(Cow::Owned(x)) => v.visit_byte_buf(x), SerdeObject::Bytes(Cow::Borrowed(x)) => v.visit_borrowed_bytes(x), - SerdeObject::Some(x) => todo!(), + SerdeObject::Some(x) => v.visit_some(x.into_deserializer()), SerdeObject::None => v.visit_none(), SerdeObject::Unit => v.visit_unit(), SerdeObject::Seq(x) => todo!(), SerdeObject::Map(x) => todo!(), - SerdeObject::NewtypeStruct(x) => todo!(), + SerdeObject::NewtypeStruct(x) => { + v.visit_newtype_struct(x.into_deserializer()) + }, SerdeObject::Enum { variant, data } => todo!(), } } @@ -515,7 +548,8 @@ mod tests { fn test_broken() { let consts = PatternConstants::<()>::default(); let mut err = Default::default(); - let interp = Interpreter::new(&consts, &mut err); + let frames = Default::default(); + let interp = Interpreter::new(&consts, &mut err, &frames); let _ = Packer::new(interp, MAX_CALLS); } @@ -524,7 +558,8 @@ mod tests { let mut consts = PatternConstants::<()>::default(); consts.protos.push(Vec::new()); let mut err = Default::default(); - let interp = Interpreter::new(&consts, &mut err); + let frames = Default::default(); + let interp = Interpreter::new(&consts, &mut err, &frames); let _ = Packer::new(interp, MAX_CALLS); } @@ -534,7 +569,8 @@ mod tests { consts.protos.push(Vec::new()); let mut der = JsonDeserializer::from_str("{}"); let mut err = Default::default(); - let interp = Interpreter::new(&consts, &mut err); + let frames = Default::default(); + let interp = Interpreter::new(&consts, &mut err, &frames); let pack = Packer::new(interp, MAX_CALLS).deserialize(&mut der).unwrap(); } @@ -552,8 +588,11 @@ mod tests { ]); let mut der = JsonDeserializer::from_str("3"); let mut err = Default::default(); - let interp = Interpreter::new(&consts, &mut err); - let pack = Packer::new(interp, MAX_CALLS).deserialize(&mut der).unwrap().0; + let frames = Default::default(); + let interp = Interpreter::new(&consts, &mut err, &frames); + let packed = Packer::new(interp, MAX_CALLS).deserialize(&mut der); + let (pack, obj) = packed.unwrap(); + assert!(obj.is_none()); assert_eq!(pack.subpacks[0]["hello"].1, SerdeObject::U64(3)); } } |