mirror of
https://github.com/nushell/nushell
synced 2025-01-15 06:34:15 +00:00
Merge branch 'master' of github.com:nushell/nushell
This commit is contained in:
commit
fa859f1461
13 changed files with 221 additions and 203 deletions
|
@ -4,6 +4,6 @@ root = true
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = true
|
||||||
insert_final_newline = false
|
insert_final_newline = false
|
||||||
end_of_line = lf
|
end_of_line = lf
|
|
@ -1,5 +1,4 @@
|
||||||
#![feature(generators)]
|
#![feature(generators)]
|
||||||
#![feature(specialization)]
|
|
||||||
#![feature(proc_macro_hygiene)]
|
#![feature(proc_macro_hygiene)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::object::base as value;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
|
|
||||||
|
@ -6,29 +5,6 @@ pub trait ExtractType: Sized {
|
||||||
fn extract(value: &Tagged<Value>) -> Result<Self, ShellError>;
|
fn extract(value: &Tagged<Value>) -> Result<Self, ShellError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ExtractType for T {
|
|
||||||
default fn extract(_value: &Tagged<Value>) -> Result<T, ShellError> {
|
|
||||||
let name = std::any::type_name::<T>();
|
|
||||||
Err(ShellError::unimplemented(format!(
|
|
||||||
"<T> ExtractType for {}",
|
|
||||||
name
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T: ExtractType> ExtractType for Option<T> {
|
|
||||||
fn extract(value: &Tagged<Value>) -> Result<Option<T>, ShellError> {
|
|
||||||
let name = std::any::type_name::<T>();
|
|
||||||
trace!("<Option> Extracting {:?} for Option<{}>", value, name);
|
|
||||||
|
|
||||||
let result = match value.item() {
|
|
||||||
Value::Primitive(Primitive::Nothing) => None,
|
|
||||||
_ => Some(T::extract(value)?),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ExtractType> ExtractType for Tagged<T> {
|
impl<T: ExtractType> ExtractType for Tagged<T> {
|
||||||
fn extract(value: &Tagged<Value>) -> Result<Tagged<T>, ShellError> {
|
fn extract(value: &Tagged<Value>) -> Result<Tagged<T>, ShellError> {
|
||||||
let name = std::any::type_name::<T>();
|
let name = std::any::type_name::<T>();
|
||||||
|
@ -38,14 +14,6 @@ impl<T: ExtractType> ExtractType for Tagged<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtractType for Value {
|
|
||||||
fn extract(value: &Tagged<Value>) -> Result<Value, ShellError> {
|
|
||||||
trace!("<Tagged> Extracting {:?} for Value", value);
|
|
||||||
|
|
||||||
Ok(value.item().clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExtractType for bool {
|
impl ExtractType for bool {
|
||||||
fn extract(value: &Tagged<Value>) -> Result<bool, ShellError> {
|
fn extract(value: &Tagged<Value>) -> Result<bool, ShellError> {
|
||||||
trace!("Extracting {:?} for bool", value);
|
trace!("Extracting {:?} for bool", value);
|
||||||
|
@ -119,15 +87,3 @@ impl ExtractType for String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtractType for value::Block {
|
|
||||||
fn extract(value: &Tagged<Value>) -> Result<value::Block, ShellError> {
|
|
||||||
match value {
|
|
||||||
Tagged {
|
|
||||||
item: Value::Block(block),
|
|
||||||
..
|
|
||||||
} => Ok(block.clone()),
|
|
||||||
other => Err(ShellError::type_error("Block", other.tagged_type_name())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use serde::de;
|
use serde::de;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DeserializerItem<'de> {
|
pub struct DeserializerItem<'de> {
|
||||||
|
@ -293,6 +294,22 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut ConfigDeserializer<'de> {
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
|
fn visit<'de, T, V>(
|
||||||
|
val: T,
|
||||||
|
name: &'static str,
|
||||||
|
fields: &'static [&'static str],
|
||||||
|
visitor: V
|
||||||
|
) -> Result<V::Value, ShellError>
|
||||||
|
where
|
||||||
|
T: serde::Serialize,
|
||||||
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
|
let json = serde_json::to_string(&val)?;
|
||||||
|
let json_cursor = std::io::Cursor::new(json.into_bytes());
|
||||||
|
let mut json_de = serde_json::Deserializer::from_reader(json_cursor);
|
||||||
|
let r = json_de.deserialize_struct(name, fields, visitor)?;
|
||||||
|
return Ok(r);
|
||||||
|
}
|
||||||
trace!(
|
trace!(
|
||||||
"deserializing struct {:?} {:?} (stack={:?})",
|
"deserializing struct {:?} {:?} (stack={:?})",
|
||||||
name,
|
name,
|
||||||
|
@ -300,14 +317,60 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut ConfigDeserializer<'de> {
|
||||||
self.stack
|
self.stack
|
||||||
);
|
);
|
||||||
|
|
||||||
if self.saw_root {
|
if !self.saw_root {
|
||||||
let value = self.pop();
|
|
||||||
let name = std::any::type_name::<V::Value>();
|
|
||||||
trace!("Extracting {:?} for {:?}", value.val, name);
|
|
||||||
V::Value::extract(&value.val)
|
|
||||||
} else {
|
|
||||||
self.saw_root = true;
|
self.saw_root = true;
|
||||||
visitor.visit_seq(StructDeserializer::new(&mut self, fields))
|
return visitor.visit_seq(StructDeserializer::new(&mut self, fields));
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = self.pop();
|
||||||
|
|
||||||
|
let type_name = std::any::type_name::<V::Value>();
|
||||||
|
let tagged_val_name = std::any::type_name::<Tagged<Value>>();
|
||||||
|
|
||||||
|
if name == tagged_val_name {
|
||||||
|
return visit::<Tagged<Value>, _>(value.val, name, fields, visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if name == "Block" {
|
||||||
|
let block = match value.val {
|
||||||
|
Tagged {
|
||||||
|
item: Value::Block(block),
|
||||||
|
..
|
||||||
|
} => block,
|
||||||
|
other => return Err(ShellError::type_error("Block", other.tagged_type_name())),
|
||||||
|
};
|
||||||
|
return visit::<value::Block, _>(block, name, fields, visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
trace!("Extracting {:?} for {:?}", value.val, type_name);
|
||||||
|
|
||||||
|
let tag = value.val.tag();
|
||||||
|
match value.val {
|
||||||
|
Tagged {
|
||||||
|
item: Value::Primitive(Primitive::Boolean(b)),
|
||||||
|
..
|
||||||
|
} => visit::<Tagged<bool>, _>(b.tagged(tag), name, fields, visitor),
|
||||||
|
Tagged {
|
||||||
|
item: Value::Primitive(Primitive::Nothing),
|
||||||
|
..
|
||||||
|
} => visit::<Tagged<bool>, _>(false.tagged(tag), name, fields, visitor),
|
||||||
|
Tagged {
|
||||||
|
item: Value::Primitive(Primitive::Path(p)),
|
||||||
|
..
|
||||||
|
} => visit::<Tagged<PathBuf>, _>(p.clone().tagged(tag), name, fields, visitor),
|
||||||
|
Tagged {
|
||||||
|
item: Value::Primitive(Primitive::Int(int)),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let i: i64 = int.tagged(value.val.tag).coerce_into("converting to i64")?;
|
||||||
|
visit::<Tagged<i64>, _>(i.tagged(tag), name, fields, visitor)
|
||||||
|
},
|
||||||
|
Tagged {
|
||||||
|
item: Value::Primitive(Primitive::String(string)),
|
||||||
|
..
|
||||||
|
} => visit::<Tagged<String>, _>(string.tagged(tag), name, fields, visitor),
|
||||||
|
|
||||||
|
other => return Err(ShellError::type_error(name, other.tagged_type_name())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn deserialize_enum<V>(
|
fn deserialize_enum<V>(
|
||||||
|
|
|
@ -37,8 +37,8 @@ impl NuCompleter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let line_chars: Vec<_> = line.chars().collect();
|
let line_chars: Vec<_> = line[..pos].chars().collect();
|
||||||
let mut replace_pos = pos;
|
let mut replace_pos = line_chars.len();
|
||||||
while replace_pos > 0 {
|
while replace_pos > 0 {
|
||||||
if line_chars[replace_pos - 1] == ' ' {
|
if line_chars[replace_pos - 1] == ' ' {
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue