use log::trace; use nu_errors::{CoerceInto, ShellError}; use nu_protocol::{ hir::Commands, CallInfo, ColumnPath, Primitive, RangeInclusion, ShellTypeName, UntaggedValue, Value, }; use nu_source::{HasSpan, Spanned, SpannedItem, Tagged, TaggedItem}; use nu_value_ext::ValueExt; use serde::de; use serde::{Deserialize, Serialize}; use std::path::PathBuf; #[derive(Copy, Clone, Deserialize, Serialize)] pub struct NumericRange { pub from: (Spanned, RangeInclusion), pub to: (Spanned, RangeInclusion), } #[derive(Debug)] pub struct DeserializerItem<'de> { key_struct_field: Option<(String, &'de str)>, val: Value, } pub struct ConfigDeserializer<'de> { call: CallInfo, stack: Vec>, saw_root: bool, position: usize, } impl<'de> ConfigDeserializer<'de> { pub fn from_call_info(call: CallInfo) -> ConfigDeserializer<'de> { ConfigDeserializer { call, stack: vec![], saw_root: false, position: 0, } } pub fn push_val(&mut self, val: Value) { 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); self.position += positional.len(); Some(UntaggedValue::Table(positional).into_untagged_value()) // TODO: correct tag } else if self.call.args.has(name) { self.call.args.get(name).cloned() } else { let position = self.position; self.position += 1; self.call.args.nth(position).cloned() }; trace!("pushing {:?}", value); self.stack.push(DeserializerItem { key_struct_field: Some((name.to_string(), name)), val: value.unwrap_or_else(|| UntaggedValue::nothing().into_value(&self.call.name_tag)), }); Ok(()) } pub fn top(&mut self) -> &DeserializerItem { let value = self.stack.last(); trace!("inspecting top value :: {:?}", value); value.expect("Can't get top element of an empty stack") } pub fn pop(&mut self) -> DeserializerItem { let value = self.stack.pop(); trace!("popping value :: {:?}", value); value.expect("Can't pop an empty stack") } } use de::Visitor; impl<'de, 'a> de::Deserializer<'de> for &'a mut ConfigDeserializer<'de> { type Error = ShellError; fn deserialize_any(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_any") } fn deserialize_bool(self, visitor: V) -> Result where V: Visitor<'de>, { let value = self.pop(); trace!("Extracting {:?} for bool", value.val); match &value.val { Value { value: UntaggedValue::Primitive(Primitive::Boolean(b)), .. } => visitor.visit_bool(*b), Value { value: UntaggedValue::Primitive(Primitive::Nothing), .. } => visitor.visit_bool(false), other => Err(ShellError::type_error( "Boolean", other.type_name().spanned(other.span()), )), } } fn deserialize_i8(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_i8") } fn deserialize_i16(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_i16") } fn deserialize_i32(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_i32") } fn deserialize_i64(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_i64") } fn deserialize_u8(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_u8") } fn deserialize_u16(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_u16") } fn deserialize_u32(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_u32") } fn deserialize_u64(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_u64") } fn deserialize_f32(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_f32") } fn deserialize_f64(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_f64") } fn deserialize_char(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_char") } fn deserialize_str(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_str") } fn deserialize_string(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_string") } fn deserialize_bytes(self, _visitor: V) -> Result where V: Visitor<'de>, { unimplemented!("deserialize_bytes") } fn deserialize_byte_buf(self, _visitor: V) -> Result where V: Visitor<'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!("