summary refs log tree commit diff stats
path: root/src/vm/de.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/de.rs')
-rw-r--r--src/vm/de.rs259
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));
     }
 }