From 5491b5485945385a83c72a057696287fdab827b5 Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 2 Sep 2019 02:43:07 +0200 Subject: [PATCH 1/6] Make key and struct_field optional in DeserializerItem The main point of this struct seems to be debugging, as key_struct_field is unused except for debugging. --- src/parser/deserializer.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/parser/deserializer.rs b/src/parser/deserializer.rs index 8d6e74828e..9f753ced86 100644 --- a/src/parser/deserializer.rs +++ b/src/parser/deserializer.rs @@ -4,8 +4,7 @@ use serde::{de, forward_to_deserialize_any}; #[derive(Debug)] pub struct DeserializerItem<'de> { - key: String, - struct_field: &'de str, + key_struct_field: Option<(String, &'de str)>, val: Tagged, } @@ -44,8 +43,7 @@ impl<'de> ConfigDeserializer<'de> { trace!("pushing {:?}", value); self.stack.push(DeserializerItem { - key: name.to_string(), - struct_field: name, + key_struct_field: Some((name.to_string(), name)), val: value.unwrap_or_else(|| { Value::nothing().tagged(Tag::unknown_origin(self.call.name_span)) }), From 79a779dbea7f4752df052f874d0eb47b091c514d Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 2 Sep 2019 03:25:34 +0200 Subject: [PATCH 2/6] Deserialize vecs with serde --- src/object/types.rs | 23 -------------- src/parser/deserializer.rs | 62 +++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 24 deletions(-) diff --git a/src/object/types.rs b/src/object/types.rs index b98e4b5494..e766cbaf4e 100644 --- a/src/object/types.rs +++ b/src/object/types.rs @@ -16,29 +16,6 @@ impl ExtractType for T { } } -impl ExtractType for Vec> { - fn extract(value: &Tagged) -> Result { - let name = std::any::type_name::(); - trace!(" Extracting {:?} for Vec<{}>", value, name); - - match value.item() { - Value::List(items) => { - let mut out = vec![]; - - for item in items { - out.push(T::extract(item)?.tagged(item.tag())); - } - - Ok(out) - } - other => Err(ShellError::type_error( - "Vec", - other.type_name().tagged(value.tag()), - )), - } - } -} - impl ExtractType for (T, U) { fn extract(value: &Tagged) -> Result<(T, U), ShellError> { let t_name = std::any::type_name::(); diff --git a/src/parser/deserializer.rs b/src/parser/deserializer.rs index 9f753ced86..66f83c6564 100644 --- a/src/parser/deserializer.rs +++ b/src/parser/deserializer.rs @@ -25,6 +25,13 @@ impl<'de> ConfigDeserializer<'de> { } } + pub fn push_val(&mut self, val: Tagged) { + self.stack.push(DeserializerItem { + key_struct_field: None, + val, + }); + } + pub fn push(&mut self, name: &'static str) -> Result<(), ShellError> { let value: Option> = if name == "rest" { let positional = self.call.args.slice_from(self.position); @@ -74,7 +81,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut ConfigDeserializer<'de> { V::Value::extract(&value.val) } - forward_to_deserialize_any! { bool option seq } + forward_to_deserialize_any! { bool option } fn deserialize_i8(self, _visitor: V) -> Result where @@ -193,7 +200,24 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut ConfigDeserializer<'de> { { unimplemented!("deserialize_newtype_struct") } + fn deserialize_seq(mut self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let value = self.pop(); + trace!(" Extracting {:?} for vec", value.val); + match value.val.into_parts() { + (Value::List(items), _) => { + let de = SeqDeserializer::new(&mut self, items.into_iter()); + visitor.visit_seq(de) + } + (other, tag) => Err(ShellError::type_error( + "Vec", + other.type_name().tagged(tag), + )), + } + } fn deserialize_tuple(self, _len: usize, _visitor: V) -> Result where V: Visitor<'de>, @@ -268,6 +292,42 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut ConfigDeserializer<'de> { } } +struct SeqDeserializer<'a, 'de: 'a, I: Iterator>> { + de: &'a mut ConfigDeserializer<'de>, + vals: I, +} + +impl<'a, 'de: 'a, I: Iterator>> SeqDeserializer<'a, 'de, I> { + fn new(de: &'a mut ConfigDeserializer<'de>, vals: I) -> Self { + SeqDeserializer { + de, + vals, + } + } +} + +impl<'a, 'de: 'a, I: Iterator>> de::SeqAccess<'de> for SeqDeserializer<'a, 'de, I> { + type Error = ShellError; + + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + let next = if let Some(next) = self.vals.next() { + next + } else { + return Ok(None); + }; + + self.de.push_val(next); + seed.deserialize(&mut *self.de).map(Some) + } + + fn size_hint(&self) -> Option { + return self.vals.size_hint().1; + } +} + struct StructDeserializer<'a, 'de: 'a> { de: &'a mut ConfigDeserializer<'de>, fields: &'static [&'static str], From e8bbd330e08c4d2fd34195db52f984c64ab967d7 Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 2 Sep 2019 03:37:01 +0200 Subject: [PATCH 3/6] Deserialize tuples with serde --- src/object/types.rs | 30 ------------------------------ src/parser/deserializer.rs | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/src/object/types.rs b/src/object/types.rs index e766cbaf4e..ea1a5dbeea 100644 --- a/src/object/types.rs +++ b/src/object/types.rs @@ -15,36 +15,6 @@ impl ExtractType for T { ))) } } - -impl ExtractType for (T, U) { - fn extract(value: &Tagged) -> Result<(T, U), ShellError> { - let t_name = std::any::type_name::(); - let u_name = std::any::type_name::(); - - trace!("Extracting {:?} for ({}, {})", value, t_name, u_name); - - match value.item() { - Value::List(items) => { - if items.len() == 2 { - let first = &items[0]; - let second = &items[1]; - - Ok((T::extract(first)?, U::extract(second)?)) - } else { - Err(ShellError::type_error( - "two-element-tuple", - "not-two".tagged(value.tag()), - )) - } - } - other => Err(ShellError::type_error( - "two-element-tuple", - other.type_name().tagged(value.tag()), - )), - } - } -} - impl ExtractType for Option { fn extract(value: &Tagged) -> Result, ShellError> { let name = std::any::type_name::(); diff --git a/src/parser/deserializer.rs b/src/parser/deserializer.rs index 66f83c6564..48b4239f4f 100644 --- a/src/parser/deserializer.rs +++ b/src/parser/deserializer.rs @@ -218,11 +218,23 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut ConfigDeserializer<'de> { )), } } - fn deserialize_tuple(self, _len: usize, _visitor: V) -> Result + fn deserialize_tuple(mut self, len: usize, visitor: V) -> Result where V: Visitor<'de>, { - unimplemented!("deserialize_tuple") + let value = self.pop(); + trace!(" Extracting {:?} for tuple with {} elements", value.val, len); + + match value.val.into_parts() { + (Value::List(items), _) => { + let de = SeqDeserializer::new(&mut self, items.into_iter()); + visitor.visit_seq(de) + } + (other, tag) => Err(ShellError::type_error( + "Tuple", + other.type_name().tagged(tag), + )), + } } fn deserialize_tuple_struct( self, From a69a0bc5ee7ec476bdec9028a029b903af5a6185 Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 2 Sep 2019 00:32:26 +0200 Subject: [PATCH 4/6] Use serde to deserialize options --- src/parser/deserializer.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/parser/deserializer.rs b/src/parser/deserializer.rs index 48b4239f4f..d9d6853190 100644 --- a/src/parser/deserializer.rs +++ b/src/parser/deserializer.rs @@ -58,6 +58,12 @@ impl<'de> ConfigDeserializer<'de> { Ok(()) } + + pub fn top(&mut self) -> &DeserializerItem { + let value = self.stack.last(); + trace!("inspecting top value :: {:?}", value); + value.expect("Can't get top elemant of an empty stack") + } pub fn pop(&mut self) -> DeserializerItem { let value = self.stack.pop(); @@ -81,7 +87,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut ConfigDeserializer<'de> { V::Value::extract(&value.val) } - forward_to_deserialize_any! { bool option } + forward_to_deserialize_any! { bool } fn deserialize_i8(self, _visitor: V) -> Result where @@ -173,6 +179,19 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut ConfigDeserializer<'de> { { unimplemented!("deserialize_byte_buf") } + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let value = self.top(); + let name = std::any::type_name::(); + trace!("