diff --git a/src/object/types.rs b/src/object/types.rs index 74ea03ac67..2f17ed6f03 100644 --- a/src/object/types.rs +++ b/src/object/types.rs @@ -15,59 +15,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::(); - 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 8d6e74828e..33e4b9ead2 100644 --- a/src/parser/deserializer.rs +++ b/src/parser/deserializer.rs @@ -1,11 +1,10 @@ use crate::prelude::*; use log::trace; -use serde::{de, forward_to_deserialize_any}; +use serde::de; #[derive(Debug)] pub struct DeserializerItem<'de> { - key: String, - struct_field: &'de str, + key_struct_field: Option<(String, &'de str)>, val: Tagged, } @@ -26,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); @@ -44,8 +50,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)) }), @@ -53,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(); @@ -69,15 +80,27 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut ConfigDeserializer<'de> { where V: Visitor<'de>, { - let value = self.pop(); - let name = std::any::type_name::(); - trace!(" Extracting {:?}", name); - - V::Value::extract(&value.val) + unimplemented!("deserialize_any") } + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let value = self.pop(); + trace!("Extracting {:?} for bool", value.val); - forward_to_deserialize_any! { bool option seq } - + match &value.val { + Tagged { + item: Value::Primitive(Primitive::Boolean(b)), + .. + } => visitor.visit_bool(*b), + Tagged { + item: Value::Primitive(Primitive::Nothing), + .. + } => visitor.visit_bool(false), + other => Err(ShellError::type_error("Boolean", other.tagged_type_name())), + } + } fn deserialize_i8(self, _visitor: V) -> Result where V: Visitor<'de>, @@ -168,6 +191,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!("