From 99671b8ffcb4c0ed4bd5b9168a443e96797fa4e1 Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Mon, 5 Aug 2019 20:54:29 +1200 Subject: [PATCH] Move more parts to tags and away from spans --- src/cli.rs | 12 +- src/commands/cd.rs | 2 +- src/commands/classified.rs | 21 ++-- src/commands/command.rs | 6 +- src/commands/config.rs | 23 ++-- src/commands/date.rs | 18 +-- src/commands/first.rs | 2 +- src/commands/from_csv.rs | 28 +++-- src/commands/from_ini.rs | 34 ++--- src/commands/from_json.rs | 46 +++---- src/commands/from_toml.rs | 44 ++++--- src/commands/from_xml.rs | 57 +++++---- src/commands/from_yaml.rs | 44 ++++--- src/commands/get.rs | 2 +- src/commands/lines.rs | 8 +- src/commands/ls.rs | 15 ++- src/commands/open.rs | 160 +++++++++++++----------- src/commands/pick.rs | 4 +- src/commands/ps.rs | 2 +- src/commands/reject.rs | 13 +- src/commands/rm.rs | 2 +- src/commands/save.rs | 15 +-- src/commands/size.rs | 17 +-- src/commands/skip_while.rs | 2 +- src/commands/split_column.rs | 16 +-- src/commands/split_row.rs | 12 +- src/commands/tags.rs | 11 +- src/commands/to_csv.rs | 6 +- src/commands/to_json.rs | 8 +- src/commands/to_toml.rs | 4 +- src/commands/to_yaml.rs | 8 +- src/commands/trim.rs | 2 +- src/context.rs | 4 +- src/errors.rs | 39 +++--- src/evaluate/evaluator.rs | 18 ++- src/object/base.rs | 28 ++--- src/object/config.rs | 2 +- src/object/dict.rs | 20 +-- src/object/files.rs | 4 +- src/object/into.rs | 2 +- src/object/meta.rs | 98 ++++++++++----- src/object/process.rs | 4 +- src/object/types.rs | 2 +- src/parser/hir.rs | 12 +- src/parser/hir/baseline_parse_tokens.rs | 40 +++--- src/parser/parse/parser.rs | 12 +- src/parser/parse/token_tree_builder.rs | 37 +++--- src/parser/parse_command.rs | 4 +- src/parser/registry.rs | 6 +- src/plugins/add.rs | 4 +- src/plugins/binaryview.rs | 7 +- src/plugins/edit.rs | 4 +- src/plugins/inc.rs | 12 +- src/plugins/str.rs | 46 ++++--- src/plugins/sum.rs | 10 +- src/plugins/sys.rs | 56 ++++----- src/plugins/textview.rs | 4 +- 57 files changed, 627 insertions(+), 492 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index e57824fb13..7ab43567dc 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -348,7 +348,7 @@ async fn process_line(readline: Result, ctx: &mut Context Some(ClassifiedCommand::External(_)) => {} _ => pipeline.commands.push(ClassifiedCommand::Sink(SinkCommand { command: sink("autoview", Box::new(autoview::autoview)), - name_span: None, + name_span: Span::unknown(), args: registry::Args { positional: None, named: None, @@ -382,7 +382,7 @@ async fn process_line(readline: Result, ctx: &mut Context } (Some(ClassifiedCommand::Sink(SinkCommand { name_span, .. })), Some(_)) => { - return LineResult::Error(line.clone(), ShellError::maybe_labeled_error("Commands like table, save, and autoview must come last in the pipeline", "must come last", name_span)); + return LineResult::Error(line.clone(), ShellError::labeled_error("Commands like table, save, and autoview must come last in the pipeline", "must come last", name_span)); } (Some(ClassifiedCommand::Sink(left)), None) => { @@ -496,7 +496,7 @@ fn classify_command( Ok(ClassifiedCommand::Internal(InternalCommand { command, - name_span: Some(head.span().clone()), + name_span: head.span().clone(), args, })) } @@ -510,7 +510,7 @@ fn classify_command( Ok(ClassifiedCommand::Sink(SinkCommand { command, - name_span: Some(head.span().clone()), + name_span: head.span().clone(), args, })) } @@ -521,7 +521,7 @@ fn classify_command( .iter() .filter_map(|i| match i { TokenNode::Whitespace(_) => None, - other => Some(Tagged::from_item( + other => Some(Tagged::from_simple_spanned_item( other.as_external_arg(source), other.span(), )), @@ -532,7 +532,7 @@ fn classify_command( Ok(ClassifiedCommand::External(ExternalCommand { name: name.to_string(), - name_span: Some(head.span().clone()), + name_span: head.span().clone(), args: arg_list_strings, })) } diff --git a/src/commands/cd.rs b/src/commands/cd.rs index bd2b5ba913..dd4fca3397 100644 --- a/src/commands/cd.rs +++ b/src/commands/cd.rs @@ -10,7 +10,7 @@ pub fn cd(args: CommandArgs) -> Result { None => match dirs::home_dir() { Some(o) => o, _ => { - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( "Can not change to home directory", "can not go to home", args.call_info.name_span, diff --git a/src/commands/classified.rs b/src/commands/classified.rs index 7963fb8230..c09fdfc2b9 100644 --- a/src/commands/classified.rs +++ b/src/commands/classified.rs @@ -99,7 +99,7 @@ impl ClassifiedCommand { crate struct SinkCommand { crate command: Arc, - crate name_span: Option, + crate name_span: Span, crate args: Args, } @@ -111,7 +111,7 @@ impl SinkCommand { crate struct InternalCommand { crate command: Arc, - crate name_span: Option, + crate name_span: Span, crate args: Args, } @@ -166,7 +166,7 @@ impl InternalCommand { crate struct ExternalCommand { crate name: String, #[allow(unused)] - crate name_span: Option, + crate name_span: Span, crate args: Vec>, } @@ -240,7 +240,10 @@ impl ExternalCommand { } else { for arg in &self.args { let arg_chars: Vec<_> = arg.chars().collect(); - if arg_chars.len() > 1 && arg_chars[0] == '"' && arg_chars[arg_chars.len() - 1] == '"' { + if arg_chars.len() > 1 + && arg_chars[0] == '"' + && arg_chars[arg_chars.len() - 1] == '"' + { // quoted string let new_arg: String = arg_chars[1..arg_chars.len() - 1].iter().collect(); process = process.arg(new_arg); @@ -258,13 +261,13 @@ impl ExternalCommand { let mut first = true; for i in &inputs { if i.as_string().is_err() { - let mut span = None; + let mut span = name_span; for arg in &self.args { if arg.item.contains("$it") { - span = Some(arg.span()); + span = arg.span(); } } - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( "External $it needs string data", "given object instead of string data", span, @@ -323,7 +326,9 @@ impl ExternalCommand { let stdout = popen.stdout.take().unwrap(); let file = futures::io::AllowStdIo::new(stdout); let stream = Framed::new(file, LinesCodec {}); - let stream = stream.map(move |line| Value::string(line.unwrap()).tagged(name_span)); + let stream = stream.map(move |line| { + Tagged::from_simple_spanned_item(Value::string(line.unwrap()), name_span) + }); Ok(ClassifiedInputStream::from_input_stream( stream.boxed() as BoxStream<'static, Tagged> )) diff --git a/src/commands/command.rs b/src/commands/command.rs index db338eaf32..645a6bca59 100644 --- a/src/commands/command.rs +++ b/src/commands/command.rs @@ -13,7 +13,7 @@ use uuid::Uuid; pub struct CallInfo { pub args: Args, pub source_map: SourceMap, - pub name_span: Option, + pub name_span: Span, } #[derive(Getters)] @@ -93,7 +93,9 @@ impl ReturnSuccess { } pub fn spanned_value(input: Value, span: Span) -> ReturnValue { - Ok(ReturnSuccess::Value(Tagged::from_item(input, span))) + Ok(ReturnSuccess::Value(Tagged::from_simple_spanned_item( + input, span, + ))) } } diff --git a/src/commands/config.rs b/src/commands/config.rs index 210d5e15cb..080e120e88 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -61,10 +61,11 @@ pub fn config(args: CommandArgs) -> Result { config::write_config(&result)?; - return Ok( - stream![Tagged::from_item(Value::Object(result.into()), v.span())] - .from_input_stream(), - ); + return Ok(stream![Tagged::from_simple_spanned_item( + Value::Object(result.into()), + v.span() + )] + .from_input_stream()); } } @@ -73,9 +74,11 @@ pub fn config(args: CommandArgs) -> Result { config::write_config(&result)?; - return Ok( - stream![Tagged::from_item(Value::Object(result.into()), c.span())].from_input_stream(), - ); + return Ok(stream![Tagged::from_simple_spanned_item( + Value::Object(result.into()), + c.span() + )] + .from_input_stream()); } if let Some(v) = args.get("remove") { @@ -90,12 +93,14 @@ pub fn config(args: CommandArgs) -> Result { ))); } - let obj = VecDeque::from_iter(vec![Value::Object(result.into()).tagged(v)]); + let obj = VecDeque::from_iter(vec![Value::Object(result.into()).simple_spanned(v)]); return Ok(obj.from_input_stream()); } if args.len() == 0 { - return Ok(vec![Value::Object(result.into()).tagged(args.call_info.name_span)].into()); + return Ok( + vec![Value::Object(result.into()).simple_spanned(args.call_info.name_span)].into(), + ); } Err(ShellError::string(format!("Unimplemented"))) diff --git a/src/commands/date.rs b/src/commands/date.rs index e50c9e6bdd..ea177459df 100644 --- a/src/commands/date.rs +++ b/src/commands/date.rs @@ -42,41 +42,41 @@ where indexmap.insert( "year".to_string(), - Tagged::from_item(Value::int(dt.year()), span), + Tagged::from_simple_spanned_item(Value::int(dt.year()), span), ); indexmap.insert( "month".to_string(), - Tagged::from_item(Value::int(dt.month()), span), + Tagged::from_simple_spanned_item(Value::int(dt.month()), span), ); indexmap.insert( "day".to_string(), - Tagged::from_item(Value::int(dt.day()), span), + Tagged::from_simple_spanned_item(Value::int(dt.day()), span), ); indexmap.insert( "hour".to_string(), - Tagged::from_item(Value::int(dt.hour()), span), + Tagged::from_simple_spanned_item(Value::int(dt.hour()), span), ); indexmap.insert( "minute".to_string(), - Tagged::from_item(Value::int(dt.minute()), span), + Tagged::from_simple_spanned_item(Value::int(dt.minute()), span), ); indexmap.insert( "second".to_string(), - Tagged::from_item(Value::int(dt.second()), span), + Tagged::from_simple_spanned_item(Value::int(dt.second()), span), ); let tz = dt.offset(); indexmap.insert( "timezone".to_string(), - Tagged::from_item(Value::string(format!("{}", tz)), span), + Tagged::from_simple_spanned_item(Value::string(format!("{}", tz)), span), ); - Tagged::from_item(Value::Object(Dictionary::from(indexmap)), span) + Tagged::from_simple_spanned_item(Value::Object(Dictionary::from(indexmap)), span) } pub fn date(args: CommandArgs) -> Result { let mut date_out = VecDeque::new(); - let span = args.call_info.name_span.unwrap(); + let span = args.call_info.name_span; let value = if args.has("utc") { let utc: DateTime = Utc::now(); diff --git a/src/commands/first.rs b/src/commands/first.rs index e4ee0e520c..96c820c3bd 100644 --- a/src/commands/first.rs +++ b/src/commands/first.rs @@ -5,7 +5,7 @@ use crate::prelude::*; pub fn first(args: CommandArgs) -> Result { if args.len() == 0 { - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( "First requires an amount", "needs parameter", args.call_info.name_span, diff --git a/src/commands/from_csv.rs b/src/commands/from_csv.rs index b86ec42619..050534f760 100644 --- a/src/commands/from_csv.rs +++ b/src/commands/from_csv.rs @@ -4,12 +4,12 @@ use csv::ReaderBuilder; pub fn from_csv_string_to_value( s: String, - span: impl Into, + tag: impl Into, ) -> Result, Box> { let mut reader = ReaderBuilder::new() .has_headers(false) .from_reader(s.as_bytes()); - let span = span.into(); + let tag = tag.into(); let mut fields: VecDeque = VecDeque::new(); let mut iter = reader.records(); @@ -27,12 +27,12 @@ pub fn from_csv_string_to_value( if let Some(row_values) = iter.next() { let row_values = row_values?; - let mut row = TaggedDictBuilder::new(span); + let mut row = TaggedDictBuilder::new(tag); for (idx, entry) in row_values.iter().enumerate() { row.insert_tagged( fields.get(idx).unwrap(), - Value::Primitive(Primitive::String(String::from(entry))).tagged(span), + Value::Primitive(Primitive::String(String::from(entry))).tagged(tag), ); } @@ -42,7 +42,7 @@ pub fn from_csv_string_to_value( } } - Ok(Tagged::from_item(Value::List(rows), span)) + Ok(Tagged::from_item(Value::List(rows), tag)) } pub fn from_csv(args: CommandArgs) -> Result { @@ -52,22 +52,26 @@ pub fn from_csv(args: CommandArgs) -> Result { Ok(out .values .map(move |a| { - let value_span = a.span(); + let value_tag = a.tag(); match a.item { Value::Primitive(Primitive::String(s)) => { - match from_csv_string_to_value(s, value_span) { + match from_csv_string_to_value(s, value_tag) { Ok(x) => ReturnSuccess::value(x), - Err(_) => Err(ShellError::maybe_labeled_error( + Err(_) => Err(ShellError::labeled_error_with_secondary( "Could not parse as CSV", - "piped data failed CSV parse", + "input cannot be parsed as CSV", span, + "value originates from here", + value_tag.span, )), } } - _ => Err(ShellError::maybe_labeled_error( - "Expected string values from pipeline", - "expects strings from pipeline", + _ => Err(ShellError::labeled_error_with_secondary( + "Expected a string from pipeline", + "requires string input", span, + "value originates from here", + a.span(), )), } }) diff --git a/src/commands/from_ini.rs b/src/commands/from_ini.rs index df7f403427..d1a8fa446e 100644 --- a/src/commands/from_ini.rs +++ b/src/commands/from_ini.rs @@ -4,9 +4,9 @@ use std::collections::HashMap; fn convert_ini_second_to_nu_value( v: &HashMap, - span: impl Into, + tag: impl Into, ) -> Tagged { - let mut second = TaggedDictBuilder::new(span); + let mut second = TaggedDictBuilder::new(tag); for (key, value) in v.into_iter() { second.insert(key.clone(), Primitive::String(value.clone())); @@ -17,13 +17,13 @@ fn convert_ini_second_to_nu_value( fn convert_ini_top_to_nu_value( v: &HashMap>, - span: impl Into, + tag: impl Into, ) -> Tagged { - let span = span.into(); - let mut top_level = TaggedDictBuilder::new(span); + let tag = tag.into(); + let mut top_level = TaggedDictBuilder::new(tag); for (key, value) in v.iter() { - top_level.insert_tagged(key.clone(), convert_ini_second_to_nu_value(value, span)); + top_level.insert_tagged(key.clone(), convert_ini_second_to_nu_value(value, tag)); } top_level.into_tagged_value() @@ -31,10 +31,10 @@ fn convert_ini_top_to_nu_value( pub fn from_ini_string_to_value( s: String, - span: impl Into, + tag: impl Into, ) -> Result, Box> { let v: HashMap> = serde_ini::from_str(&s)?; - Ok(convert_ini_top_to_nu_value(&v, span)) + Ok(convert_ini_top_to_nu_value(&v, tag)) } pub fn from_ini(args: CommandArgs) -> Result { @@ -43,22 +43,26 @@ pub fn from_ini(args: CommandArgs) -> Result { Ok(out .values .map(move |a| { - let value_span = a.span(); + let value_tag = a.tag(); match a.item { Value::Primitive(Primitive::String(s)) => { - match from_ini_string_to_value(s, value_span) { + match from_ini_string_to_value(s, value_tag) { Ok(x) => ReturnSuccess::value(x), - Err(_) => Err(ShellError::maybe_labeled_error( + Err(_) => Err(ShellError::labeled_error_with_secondary( "Could not parse as INI", - "piped data failed INI parse", + "input cannot be parsed as INI", span, + "value originates from here", + value_tag.span, )), } } - _ => Err(ShellError::maybe_labeled_error( - "Expected string values from pipeline", - "expects strings from pipeline", + _ => Err(ShellError::labeled_error_with_secondary( + "Expected a string from pipeline", + "requires string input", span, + "value originates from here", + a.span(), )), } }) diff --git a/src/commands/from_json.rs b/src/commands/from_json.rs index b01086b1a0..eb118a3f23 100644 --- a/src/commands/from_json.rs +++ b/src/commands/from_json.rs @@ -2,32 +2,32 @@ use crate::object::base::OF64; use crate::object::{Primitive, TaggedDictBuilder, Value}; use crate::prelude::*; -fn convert_json_value_to_nu_value(v: &serde_hjson::Value, span: impl Into) -> Tagged { - let span = span.into(); +fn convert_json_value_to_nu_value(v: &serde_hjson::Value, tag: impl Into) -> Tagged { + let tag = tag.into(); match v { serde_hjson::Value::Null => { - Value::Primitive(Primitive::String(String::from(""))).tagged(span) + Value::Primitive(Primitive::String(String::from(""))).tagged(tag) } - serde_hjson::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(span), + serde_hjson::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(tag), serde_hjson::Value::F64(n) => { - Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(span) + Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(tag) } - serde_hjson::Value::U64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(span), - serde_hjson::Value::I64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(span), + serde_hjson::Value::U64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(tag), + serde_hjson::Value::I64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(tag), serde_hjson::Value::String(s) => { - Value::Primitive(Primitive::String(String::from(s))).tagged(span) + Value::Primitive(Primitive::String(String::from(s))).tagged(tag) } serde_hjson::Value::Array(a) => Value::List( a.iter() - .map(|x| convert_json_value_to_nu_value(x, span)) + .map(|x| convert_json_value_to_nu_value(x, tag)) .collect(), ) - .tagged(span), + .tagged(tag), serde_hjson::Value::Object(o) => { - let mut collected = TaggedDictBuilder::new(span); + let mut collected = TaggedDictBuilder::new(tag); for (k, v) in o.iter() { - collected.insert_tagged(k.clone(), convert_json_value_to_nu_value(v, span)); + collected.insert_tagged(k.clone(), convert_json_value_to_nu_value(v, tag)); } collected.into_tagged_value() @@ -37,10 +37,10 @@ fn convert_json_value_to_nu_value(v: &serde_hjson::Value, span: impl Into) pub fn from_json_string_to_value( s: String, - span: impl Into, + tag: impl Into, ) -> serde_hjson::Result> { let v: serde_hjson::Value = serde_hjson::from_str(&s)?; - Ok(convert_json_value_to_nu_value(&v, span)) + Ok(convert_json_value_to_nu_value(&v, tag)) } pub fn from_json(args: CommandArgs) -> Result { @@ -49,22 +49,26 @@ pub fn from_json(args: CommandArgs) -> Result { Ok(out .values .map(move |a| { - let value_span = a.span(); + let value_tag = a.tag(); match a.item { Value::Primitive(Primitive::String(s)) => { - match from_json_string_to_value(s, value_span) { + match from_json_string_to_value(s, value_tag) { Ok(x) => ReturnSuccess::value(x), - Err(_) => Err(ShellError::maybe_labeled_error( + Err(_) => Err(ShellError::labeled_error_with_secondary( "Could not parse as JSON", - "piped data failed JSON parse", + "input cannot be parsed as JSON", span, + "value originates from here", + value_tag.span, )), } } - _ => Err(ShellError::maybe_labeled_error( - "Expected string values from pipeline", - "expects strings from pipeline", + _ => Err(ShellError::labeled_error_with_secondary( + "Expected a string from pipeline", + "requires string input", span, + "value originates from here", + a.span(), )), } }) diff --git a/src/commands/from_toml.rs b/src/commands/from_toml.rs index dda292ac54..79a138b8cb 100644 --- a/src/commands/from_toml.rs +++ b/src/commands/from_toml.rs @@ -2,28 +2,28 @@ use crate::object::base::OF64; use crate::object::{Primitive, TaggedDictBuilder, Value}; use crate::prelude::*; -fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into) -> Tagged { - let span = span.into(); +fn convert_toml_value_to_nu_value(v: &toml::Value, tag: impl Into) -> Tagged { + let tag = tag.into(); match v { - toml::Value::Boolean(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(span), - toml::Value::Integer(n) => Value::Primitive(Primitive::Int(*n)).tagged(span), - toml::Value::Float(n) => Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(span), - toml::Value::String(s) => Value::Primitive(Primitive::String(String::from(s))).tagged(span), + toml::Value::Boolean(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(tag), + toml::Value::Integer(n) => Value::Primitive(Primitive::Int(*n)).tagged(tag), + toml::Value::Float(n) => Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(tag), + toml::Value::String(s) => Value::Primitive(Primitive::String(String::from(s))).tagged(tag), toml::Value::Array(a) => Value::List( a.iter() - .map(|x| convert_toml_value_to_nu_value(x, span)) + .map(|x| convert_toml_value_to_nu_value(x, tag)) .collect(), ) - .tagged(span), + .tagged(tag), toml::Value::Datetime(dt) => { - Value::Primitive(Primitive::String(dt.to_string())).tagged(span) + Value::Primitive(Primitive::String(dt.to_string())).tagged(tag) } toml::Value::Table(t) => { - let mut collected = TaggedDictBuilder::new(span); + let mut collected = TaggedDictBuilder::new(tag); for (k, v) in t.iter() { - collected.insert_tagged(k.clone(), convert_toml_value_to_nu_value(v, span)); + collected.insert_tagged(k.clone(), convert_toml_value_to_nu_value(v, tag)); } collected.into_tagged_value() @@ -33,10 +33,10 @@ fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into) -> Tag pub fn from_toml_string_to_value( s: String, - span: impl Into, + tag: impl Into, ) -> Result, Box> { let v: toml::Value = s.parse::()?; - Ok(convert_toml_value_to_nu_value(&v, span)) + Ok(convert_toml_value_to_nu_value(&v, tag)) } pub fn from_toml(args: CommandArgs) -> Result { @@ -45,22 +45,26 @@ pub fn from_toml(args: CommandArgs) -> Result { Ok(out .values .map(move |a| { - let value_span = a.span(); + let value_tag = a.tag(); match a.item { Value::Primitive(Primitive::String(s)) => { - match from_toml_string_to_value(s, value_span) { + match from_toml_string_to_value(s, value_tag) { Ok(x) => ReturnSuccess::value(x), - Err(_) => Err(ShellError::maybe_labeled_error( + Err(_) => Err(ShellError::labeled_error_with_secondary( "Could not parse as TOML", - "piped data failed TOML parse", + "input cannot be parsed as TOML", span, + "value originates from here", + value_tag.span, )), } } - _ => Err(ShellError::maybe_labeled_error( - "Expected string values from pipeline", - "expects strings from pipeline", + _ => Err(ShellError::labeled_error_with_secondary( + "Expected a string from pipeline", + "requires string input", span, + "value originates from here", + a.span(), )), } }) diff --git a/src/commands/from_xml.rs b/src/commands/from_xml.rs index 082e29c226..f8e64bf6be 100644 --- a/src/commands/from_xml.rs +++ b/src/commands/from_xml.rs @@ -1,15 +1,15 @@ use crate::object::{Primitive, TaggedDictBuilder, Value}; use crate::prelude::*; -fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, span: impl Into) -> Tagged { - let span = span.into(); +fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, tag: impl Into) -> Tagged { + let tag = tag.into(); if n.is_element() { let name = n.tag_name().name().trim().to_string(); let mut children_values = vec![]; for c in n.children() { - children_values.push(from_node_to_value(&c, span)); + children_values.push(from_node_to_value(&c, tag)); } let children_values: Vec> = children_values @@ -29,31 +29,31 @@ fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, span: impl Into }) .collect(); - let mut collected = TaggedDictBuilder::new(span); + let mut collected = TaggedDictBuilder::new(tag); collected.insert(name.clone(), Value::List(children_values)); collected.into_tagged_value() } else if n.is_comment() { - Value::string("").tagged(span) + Value::string("").tagged(tag) } else if n.is_pi() { - Value::string("").tagged(span) + Value::string("").tagged(tag) } else if n.is_text() { - Value::string(n.text().unwrap()).tagged(span) + Value::string(n.text().unwrap()).tagged(tag) } else { - Value::string("").tagged(span) + Value::string("").tagged(tag) } } -fn from_document_to_value(d: &roxmltree::Document, span: impl Into) -> Tagged { - from_node_to_value(&d.root_element(), span) +fn from_document_to_value(d: &roxmltree::Document, tag: impl Into) -> Tagged { + from_node_to_value(&d.root_element(), tag) } pub fn from_xml_string_to_value( s: String, - span: impl Into, + tag: impl Into, ) -> Result, Box> { let parsed = roxmltree::Document::parse(&s)?; - Ok(from_document_to_value(&parsed, span)) + Ok(from_document_to_value(&parsed, tag)) } pub fn from_xml(args: CommandArgs) -> Result { @@ -61,20 +61,29 @@ pub fn from_xml(args: CommandArgs) -> Result { let span = args.call_info.name_span; Ok(out .values - .map(move |a| match a.item { - Value::Primitive(Primitive::String(s)) => match from_xml_string_to_value(s, span) { - Ok(x) => ReturnSuccess::value(x), - Err(_) => Err(ShellError::maybe_labeled_error( - "Could not parse as XML", - "piped data failed XML parse", + .map(move |a| { + let value_tag = a.tag(); + match a.item { + Value::Primitive(Primitive::String(s)) => { + match from_xml_string_to_value(s, value_tag) { + Ok(x) => ReturnSuccess::value(x), + Err(_) => Err(ShellError::labeled_error_with_secondary( + "Could not parse as XML", + "input cannot be parsed as XML", + span, + "value originates from here", + value_tag.span, + )), + } + } + _ => Err(ShellError::labeled_error_with_secondary( + "Expected a string from pipeline", + "requires string input", span, + "value originates from here", + a.span(), )), - }, - _ => Err(ShellError::maybe_labeled_error( - "Expected string values from pipeline", - "expects strings from pipeline", - span, - )), + } }) .to_output_stream()) } diff --git a/src/commands/from_yaml.rs b/src/commands/from_yaml.rs index 6323b8d226..b71ff59d73 100644 --- a/src/commands/from_yaml.rs +++ b/src/commands/from_yaml.rs @@ -2,31 +2,31 @@ use crate::object::base::OF64; use crate::object::{Primitive, TaggedDictBuilder, Value}; use crate::prelude::*; -fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, span: impl Into) -> Tagged { - let span = span.into(); +fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, tag: impl Into) -> Tagged { + let tag = tag.into(); match v { - serde_yaml::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(span), + serde_yaml::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(tag), serde_yaml::Value::Number(n) if n.is_i64() => { - Value::Primitive(Primitive::Int(n.as_i64().unwrap())).tagged(span) + Value::Primitive(Primitive::Int(n.as_i64().unwrap())).tagged(tag) } serde_yaml::Value::Number(n) if n.is_f64() => { - Value::Primitive(Primitive::Float(OF64::from(n.as_f64().unwrap()))).tagged(span) + Value::Primitive(Primitive::Float(OF64::from(n.as_f64().unwrap()))).tagged(tag) } - serde_yaml::Value::String(s) => Value::string(s).tagged(span), + serde_yaml::Value::String(s) => Value::string(s).tagged(tag), serde_yaml::Value::Sequence(a) => Value::List( a.iter() - .map(|x| convert_yaml_value_to_nu_value(x, span)) + .map(|x| convert_yaml_value_to_nu_value(x, tag)) .collect(), ) - .tagged(span), + .tagged(tag), serde_yaml::Value::Mapping(t) => { - let mut collected = TaggedDictBuilder::new(span); + let mut collected = TaggedDictBuilder::new(tag); for (k, v) in t.iter() { match k { serde_yaml::Value::String(k) => { - collected.insert_tagged(k.clone(), convert_yaml_value_to_nu_value(v, span)); + collected.insert_tagged(k.clone(), convert_yaml_value_to_nu_value(v, tag)); } _ => unimplemented!("Unknown key type"), } @@ -34,17 +34,17 @@ fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, span: impl Into) collected.into_tagged_value() } - serde_yaml::Value::Null => Value::Primitive(Primitive::Nothing).tagged(span), + serde_yaml::Value::Null => Value::Primitive(Primitive::Nothing).tagged(tag), x => unimplemented!("Unsupported yaml case: {:?}", x), } } pub fn from_yaml_string_to_value( s: String, - span: impl Into, + tag: impl Into, ) -> serde_yaml::Result> { let v: serde_yaml::Value = serde_yaml::from_str(&s)?; - Ok(convert_yaml_value_to_nu_value(&v, span)) + Ok(convert_yaml_value_to_nu_value(&v, tag)) } pub fn from_yaml(args: CommandArgs) -> Result { @@ -53,22 +53,26 @@ pub fn from_yaml(args: CommandArgs) -> Result { Ok(out .values .map(move |a| { - let value_span = a.span(); + let value_tag = a.tag(); match a.item { Value::Primitive(Primitive::String(s)) => { - match from_yaml_string_to_value(s, value_span) { + match from_yaml_string_to_value(s, value_tag) { Ok(x) => ReturnSuccess::value(x), - Err(_) => Err(ShellError::maybe_labeled_error( + Err(_) => Err(ShellError::labeled_error_with_secondary( "Could not parse as YAML", - "piped data failed YAML parse", + "input cannot be parsed as YAML", span, + "value originates from here", + value_tag.span, )), } } - _ => Err(ShellError::maybe_labeled_error( - "Expected string values from pipeline", - "expects strings from pipeline", + _ => Err(ShellError::labeled_error_with_secondary( + "Expected a string from pipeline", + "requires string input", span, + "value originates from here", + a.span(), )), } }) diff --git a/src/commands/get.rs b/src/commands/get.rs index d5b4454acd..38d847156f 100644 --- a/src/commands/get.rs +++ b/src/commands/get.rs @@ -22,7 +22,7 @@ fn get_member(path: &str, span: Span, obj: &Tagged) -> Result Result { if args.len() == 0 { - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( "Get requires a field or field path", "needs parameter", args.call_info.name_span, diff --git a/src/commands/lines.rs b/src/commands/lines.rs index 05eaf1000f..8999e14090 100644 --- a/src/commands/lines.rs +++ b/src/commands/lines.rs @@ -27,10 +27,12 @@ pub fn lines(args: CommandArgs) -> Result { } _ => { let mut result = VecDeque::new(); - result.push_back(Err(ShellError::maybe_labeled_error( - "Expected string values from pipeline", - "expects strings from pipeline", + result.push_back(Err(ShellError::labeled_error_with_secondary( + "Expected a string from pipeline", + "requires string input", span, + "value originates from here", + v.span(), ))); result } diff --git a/src/commands/ls.rs b/src/commands/ls.rs index 9583ed99ca..edbd861fca 100644 --- a/src/commands/ls.rs +++ b/src/commands/ls.rs @@ -37,7 +37,7 @@ pub fn ls(args: CommandArgs) -> Result { s.span(), )); } else { - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( e.to_string(), e.to_string(), args.call_info.name_span, @@ -50,8 +50,11 @@ pub fn ls(args: CommandArgs) -> Result { let entry = entry?; let filepath = entry.path(); let filename = filepath.strip_prefix(&cwd).unwrap(); - let value = - dir_entry_dict(filename, &entry.metadata()?, args.call_info.name_span)?; + let value = dir_entry_dict( + filename, + &entry.metadata()?, + Tag::unknown_origin(args.call_info.name_span), + )?; shell_entries.push_back(ReturnSuccess::value(value)) } return Ok(shell_entries.to_output_stream()); @@ -64,7 +67,11 @@ pub fn ls(args: CommandArgs) -> Result { if let Ok(entry) = entry { let filename = entry.strip_prefix(&cwd).unwrap(); let metadata = std::fs::metadata(&entry)?; - let value = dir_entry_dict(filename, &metadata, args.call_info.name_span)?; + let value = dir_entry_dict( + filename, + &metadata, + Tag::unknown_origin(args.call_info.name_span), + )?; shell_entries.push_back(ReturnSuccess::value(value)) } } diff --git a/src/commands/open.rs b/src/commands/open.rs index c454b36fe1..933e743288 100644 --- a/src/commands/open.rs +++ b/src/commands/open.rs @@ -20,9 +20,9 @@ command! { let full_path = PathBuf::from(cwd); - let path_str = path.to_str().ok_or(ShellError::type_error("Path", "invalid path".tagged(path.span())))?; + let path_str = path.to_str().ok_or(ShellError::type_error("Path", "invalid path".simple_spanned(path.span())))?; - let (file_extension, contents, contents_span, span_source) = fetch(&full_path, path_str, path.span())?; + let (file_extension, contents, contents_tag, span_source) = fetch(&full_path, path_str, path.span())?; let file_extension = if raw.is_present() { None @@ -32,7 +32,7 @@ command! { let mut stream = VecDeque::new(); - if let Some(uuid) = contents_span.source { + if let Some(uuid) = contents_tag.origin { // If we have loaded something, track its source stream.push_back(ReturnSuccess::action(CommandAction::AddSpanSource(uuid, span_source))) } @@ -42,7 +42,7 @@ command! { let value = parse_as_value( file_extension, string, - contents_span, + contents_tag, span, )?; @@ -56,7 +56,7 @@ command! { } }, - other => stream.push_back(ReturnSuccess::value(other.tagged(contents_span))), + other => stream.push_back(ReturnSuccess::value(other.tagged(contents_tag))), }; stream @@ -67,7 +67,7 @@ pub fn fetch( cwd: &PathBuf, location: &str, span: Span, -) -> Result<(Option, Value, Span, SpanSource), ShellError> { +) -> Result<(Option, Value, Tag, SpanSource), ShellError> { let mut cwd = cwd.clone(); if location.starts_with("http:") || location.starts_with("https:") { let response = reqwest::get(location); @@ -79,13 +79,19 @@ pub fn fetch( (mime::APPLICATION, mime::XML) => Ok(( Some("xml".to_string()), Value::string(r.text().unwrap()), - Span::unknown_with_uuid(Uuid::new_v4()), + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(r.url().to_string()), )), (mime::APPLICATION, mime::JSON) => Ok(( Some("json".to_string()), Value::string(r.text().unwrap()), - Span::unknown_with_uuid(Uuid::new_v4()), + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(r.url().to_string()), )), (mime::APPLICATION, mime::OCTET_STREAM) => { @@ -100,7 +106,10 @@ pub fn fetch( Ok(( None, Value::Binary(buf), - Span::unknown_with_uuid(Uuid::new_v4()), + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(r.url().to_string()), )) } @@ -116,14 +125,20 @@ pub fn fetch( Ok(( Some(image_ty.to_string()), Value::Binary(buf), - Span::unknown_with_uuid(Uuid::new_v4()), + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(r.url().to_string()), )) } (mime::TEXT, mime::HTML) => Ok(( Some("html".to_string()), Value::string(r.text().unwrap()), - Span::unknown_with_uuid(Uuid::new_v4()), + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(r.url().to_string()), )), (mime::TEXT, mime::PLAIN) => { @@ -141,7 +156,10 @@ pub fn fetch( Ok(( path_extension, Value::string(r.text().unwrap()), - Span::unknown_with_uuid(Uuid::new_v4()), + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(r.url().to_string()), )) } @@ -151,7 +169,10 @@ pub fn fetch( "Not yet supported MIME type: {} {}", ty, sub_ty )), - Span::unknown_with_uuid(Uuid::new_v4()), + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(r.url().to_string()), )), } @@ -159,7 +180,10 @@ pub fn fetch( None => Ok(( None, Value::string(format!("No content type found")), - Span::unknown_with_uuid(Uuid::new_v4()), + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::Url(r.url().to_string()), )), }, @@ -179,13 +203,19 @@ pub fn fetch( cwd.extension() .map(|name| name.to_string_lossy().to_string()), Value::string(s), - Span::unknown_with_uuid(Uuid::new_v4()), + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::File(cwd.to_string_lossy().to_string()), )), Err(_) => Ok(( None, Value::Binary(bytes), - Span::unknown_with_uuid(Uuid::new_v4()), + Tag { + span, + origin: Some(Uuid::new_v4()), + }, SpanSource::File(cwd.to_string_lossy().to_string()), )), }, @@ -203,69 +233,57 @@ pub fn fetch( pub fn parse_as_value( extension: Option, contents: String, - contents_span: Span, - name_span: Option, + contents_tag: Tag, + name_span: Span, ) -> Result, ShellError> { match extension { - Some(x) if x == "csv" => { - crate::commands::from_csv::from_csv_string_to_value(contents, contents_span) - .map(|c| c.tagged(contents_span)) - .map_err(move |_| { - ShellError::maybe_labeled_error( - "Could not open as CSV", - "could not open as CSV", - name_span, - ) - }) - } + Some(x) if x == "csv" => crate::commands::from_csv::from_csv_string_to_value( + contents, + contents_tag, + ) + .map_err(move |_| { + ShellError::labeled_error("Could not open as CSV", "could not open as CSV", name_span) + }), Some(x) if x == "toml" => { - crate::commands::from_toml::from_toml_string_to_value(contents, contents_span) - .map(|c| c.tagged(contents_span)) - .map_err(move |_| { - ShellError::maybe_labeled_error( + crate::commands::from_toml::from_toml_string_to_value(contents, contents_tag).map_err( + move |_| { + ShellError::labeled_error( "Could not open as TOML", "could not open as TOML", name_span, ) - }) - } - Some(x) if x == "json" => { - crate::commands::from_json::from_json_string_to_value(contents, contents_span) - .map(|c| c.tagged(contents_span)) - .map_err(move |_| { - ShellError::maybe_labeled_error( - "Could not open as JSON", - "could not open as JSON", - name_span, - ) - }) - } - Some(x) if x == "ini" => { - crate::commands::from_ini::from_ini_string_to_value(contents, contents_span) - .map(|c| c.tagged(contents_span)) - .map_err(move |_| { - ShellError::maybe_labeled_error( - "Could not open as INI", - "could not open as INI", - name_span, - ) - }) - } - Some(x) if x == "xml" => { - crate::commands::from_xml::from_xml_string_to_value(contents, contents_span).map_err( - move |_| { - ShellError::maybe_labeled_error( - "Could not open as XML", - "could not open as XML", - name_span, - ) }, ) } - Some(x) if x == "yml" => { - crate::commands::from_yaml::from_yaml_string_to_value(contents, contents_span).map_err( + Some(x) if x == "json" => { + crate::commands::from_json::from_json_string_to_value(contents, contents_tag).map_err( move |_| { - ShellError::maybe_labeled_error( + ShellError::labeled_error( + "Could not open as JSON", + "could not open as JSON", + name_span, + ) + }, + ) + } + Some(x) if x == "ini" => crate::commands::from_ini::from_ini_string_to_value( + contents, + contents_tag, + ) + .map_err(move |_| { + ShellError::labeled_error("Could not open as INI", "could not open as INI", name_span) + }), + Some(x) if x == "xml" => crate::commands::from_xml::from_xml_string_to_value( + contents, + contents_tag, + ) + .map_err(move |_| { + ShellError::labeled_error("Could not open as XML", "could not open as XML", name_span) + }), + Some(x) if x == "yml" => { + crate::commands::from_yaml::from_yaml_string_to_value(contents, contents_tag).map_err( + move |_| { + ShellError::labeled_error( "Could not open as YAML", "could not open as YAML", name_span, @@ -274,9 +292,9 @@ pub fn parse_as_value( ) } Some(x) if x == "yaml" => { - crate::commands::from_yaml::from_yaml_string_to_value(contents, contents_span).map_err( + crate::commands::from_yaml::from_yaml_string_to_value(contents, contents_tag).map_err( move |_| { - ShellError::maybe_labeled_error( + ShellError::labeled_error( "Could not open as YAML", "could not open as YAML", name_span, @@ -284,6 +302,6 @@ pub fn parse_as_value( }, ) } - _ => Ok(Value::string(contents).tagged(contents_span)), + _ => Ok(Value::string(contents).tagged(contents_tag)), } } diff --git a/src/commands/pick.rs b/src/commands/pick.rs index 2891eda023..2470b778cc 100644 --- a/src/commands/pick.rs +++ b/src/commands/pick.rs @@ -4,7 +4,7 @@ use crate::prelude::*; pub fn pick(args: CommandArgs) -> Result { if args.len() == 0 { - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( "Pick requires fields", "needs parameter", args.call_info.name_span, @@ -17,7 +17,7 @@ pub fn pick(args: CommandArgs) -> Result { let objects = input .values - .map(move |value| select_fields(&value.item, &fields, value.span())); + .map(move |value| select_fields(&value.item, &fields, value.tag())); Ok(objects.from_input_stream()) } diff --git a/src/commands/ps.rs b/src/commands/ps.rs index 2924785a8a..f684a8d79e 100644 --- a/src/commands/ps.rs +++ b/src/commands/ps.rs @@ -10,7 +10,7 @@ pub fn ps(args: CommandArgs) -> Result { let list = list .into_iter() - .map(|(_, process)| process_dict(process, args.call_info.name_span)) + .map(|(_, process)| process_dict(process, Tag::unknown_origin(args.call_info.name_span))) .collect::>(); Ok(list.from_input_stream()) diff --git a/src/commands/reject.rs b/src/commands/reject.rs index 5b669cf579..fd30247a80 100644 --- a/src/commands/reject.rs +++ b/src/commands/reject.rs @@ -3,10 +3,8 @@ use crate::object::base::reject_fields; use crate::prelude::*; pub fn reject(args: CommandArgs) -> Result { - let name_span = args.call_info.name_span; - if args.len() == 0 { - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( "Reject requires fields", "needs parameter", args.call_info.name_span, @@ -16,11 +14,10 @@ pub fn reject(args: CommandArgs) -> Result { let fields: Result, _> = args.positional_iter().map(|a| a.as_string()).collect(); let fields = fields?; - let stream = args.input.values.map(move |item| { - reject_fields(&item, &fields, item.span()) - .into_tagged_value() - .tagged(name_span) - }); + let stream = args + .input + .values + .map(move |item| reject_fields(&item, &fields, item.tag()).into_tagged_value()); Ok(stream.from_input_stream()) } diff --git a/src/commands/rm.rs b/src/commands/rm.rs index 51dc9b6e91..578ce4ee61 100644 --- a/src/commands/rm.rs +++ b/src/commands/rm.rs @@ -61,7 +61,7 @@ pub fn rm(args: CommandArgs) -> Result { return Err(ShellError::labeled_error( "is a directory", "", - args.call_info.name_span.unwrap(), + args.call_info.name_span, )); } std::fs::remove_dir_all(&path).expect("can not remove directory"); diff --git a/src/commands/save.rs b/src/commands/save.rs index 999f5f61b0..ad9c7de2f8 100644 --- a/src/commands/save.rs +++ b/src/commands/save.rs @@ -21,18 +21,14 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> { if args.call_info.args.positional.is_none() { // If there is no filename, check the metadata for the origin filename if args.input.len() > 0 { - let span = args.input[0].span(); - match span - .source - .map(|x| args.call_info.source_map.get(&x)) - .flatten() - { + let origin = args.input[0].origin(); + match origin.map(|x| args.call_info.source_map.get(&x)).flatten() { Some(path) => match path { SpanSource::File(file) => { full_path.push(Path::new(file)); } _ => { - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( "Save requires a filepath", "needs path", args.call_info.name_span, @@ -40,7 +36,8 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> { } }, None => { - return Err(ShellError::maybe_labeled_error( + println!("Could not find origin"); + return Err(ShellError::labeled_error( "Save requires a filepath", "needs path", args.call_info.name_span, @@ -48,7 +45,7 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> { } } } else { - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( "Save requires a filepath", "needs path", args.call_info.name_span, diff --git a/src/commands/size.rs b/src/commands/size.rs index 40d78581ca..d4fc56de7b 100644 --- a/src/commands/size.rs +++ b/src/commands/size.rs @@ -4,20 +4,23 @@ use crate::prelude::*; pub fn size(args: CommandArgs) -> Result { let input = args.input; + let span = args.call_info.name_span; Ok(input .values .map(move |v| match v.item { - Value::Primitive(Primitive::String(ref s)) => ReturnSuccess::value(count(s, v.span())), - _ => Err(ShellError::maybe_labeled_error( - "Expected string values from pipeline", - "expects strings from pipeline", - Some(v.span()), + Value::Primitive(Primitive::String(ref s)) => ReturnSuccess::value(count(s, v.tag())), + _ => Err(ShellError::labeled_error_with_secondary( + "Expected a string from pipeline", + "requires string input", + span, + "value originates from here", + v.span(), )), }) .to_output_stream()) } -fn count(contents: &str, span: impl Into) -> Tagged { +fn count(contents: &str, tag: impl Into) -> Tagged { let mut lines: i64 = 0; let mut words: i64 = 0; let mut chars: i64 = 0; @@ -42,7 +45,7 @@ fn count(contents: &str, span: impl Into) -> Tagged { } } - let mut dict = TaggedDictBuilder::new(span); + let mut dict = TaggedDictBuilder::new(tag); //TODO: add back in name when we have it in the span //dict.insert("name", Value::string(name)); dict.insert("lines", Value::int(lines)); diff --git a/src/commands/skip_while.rs b/src/commands/skip_while.rs index c0aa0f3b07..21a554a5fb 100644 --- a/src/commands/skip_while.rs +++ b/src/commands/skip_while.rs @@ -27,7 +27,7 @@ impl Command for SkipWhile { pub fn skip_while(args: CommandArgs) -> Result { if args.len() == 0 { - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( "Where requires a condition", "needs condition", args.call_info.name_span, diff --git a/src/commands/split_column.rs b/src/commands/split_column.rs index e67d078acb..c3bf3e3d11 100644 --- a/src/commands/split_column.rs +++ b/src/commands/split_column.rs @@ -8,7 +8,7 @@ pub fn split_column(args: CommandArgs) -> Result { let span = args.call_info.name_span; if positional.len() == 0 { - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( "Split-column needs more information", "needs parameter (eg split-column \",\")", args.call_info.name_span, @@ -34,14 +34,14 @@ pub fn split_column(args: CommandArgs) -> Result { gen_columns.push(format!("Column{}", i + 1)); } - let mut dict = TaggedDictBuilder::new(v.span()); + let mut dict = TaggedDictBuilder::new(v.tag()); for (&k, v) in split_result.iter().zip(gen_columns.iter()) { dict.insert(v.clone(), Primitive::String(k.into())); } ReturnSuccess::value(dict.into_tagged_value()) } else if split_result.len() == (positional.len() - 1) { - let mut dict = TaggedDictBuilder::new(v.span()); + let mut dict = TaggedDictBuilder::new(v.tag()); for (&k, v) in split_result.iter().zip(positional.iter().skip(1)) { dict.insert( v.as_string().unwrap(), @@ -50,17 +50,19 @@ pub fn split_column(args: CommandArgs) -> Result { } ReturnSuccess::value(dict.into_tagged_value()) } else { - let mut dict = TaggedDictBuilder::new(v.span()); + let mut dict = TaggedDictBuilder::new(v.tag()); for k in positional.iter().skip(1) { dict.insert(k.as_string().unwrap().trim(), Primitive::String("".into())); } ReturnSuccess::value(dict.into_tagged_value()) } } - _ => Err(ShellError::maybe_labeled_error( - "Expected string values from pipeline", - "expects strings from pipeline", + _ => Err(ShellError::labeled_error_with_secondary( + "Expected a string from pipeline", + "requires string input", span, + "value originates from here", + v.span(), )), }) .to_output_stream()) diff --git a/src/commands/split_row.rs b/src/commands/split_row.rs index 1c31f951a5..b327bc2b6c 100644 --- a/src/commands/split_row.rs +++ b/src/commands/split_row.rs @@ -8,7 +8,7 @@ pub fn split_row(args: CommandArgs) -> Result { let span = args.call_info.name_span; if positional.len() == 0 { - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( "Split-row needs more information", "needs parameter (eg split-row \"\\n\")", args.call_info.name_span, @@ -30,17 +30,19 @@ pub fn split_row(args: CommandArgs) -> Result { let mut result = VecDeque::new(); for s in split_result { result.push_back(ReturnSuccess::value( - Value::Primitive(Primitive::String(s.into())).tagged(v.span()), + Value::Primitive(Primitive::String(s.into())).simple_spanned(v.span()), )); } result } _ => { let mut result = VecDeque::new(); - result.push_back(Err(ShellError::maybe_labeled_error( - "Expected string values from pipeline", - "expects strings from pipeline", + result.push_back(Err(ShellError::labeled_error_with_secondary( + "Expected a string from pipeline", + "requires string input", span, + "value originates from here", + v.span(), ))); result } diff --git a/src/commands/tags.rs b/src/commands/tags.rs index c34e458ea9..0b69ca41ab 100644 --- a/src/commands/tags.rs +++ b/src/commands/tags.rs @@ -8,18 +8,19 @@ pub fn tags(args: CommandArgs) -> Result { .input .values .map(move |v| { - let mut tags = TaggedDictBuilder::new(v.span()); + let mut tags = TaggedDictBuilder::new(v.tag()); { + let origin = v.origin(); let span = v.span(); - let mut dict = TaggedDictBuilder::new(v.span()); + let mut dict = TaggedDictBuilder::new(v.tag()); dict.insert("start", Value::int(span.start as i64)); dict.insert("end", Value::int(span.end as i64)); - match span.source.map(|x| source_map.get(&x)).flatten() { + match origin.map(|x| source_map.get(&x)).flatten() { Some(SpanSource::File(source)) => { - dict.insert("source", Value::string(source)); + dict.insert("origin", Value::string(source)); } Some(SpanSource::Url(source)) => { - dict.insert("source", Value::string(source)); + dict.insert("origin", Value::string(source)); } _ => {} } diff --git a/src/commands/to_csv.rs b/src/commands/to_csv.rs index 334696aaed..d25fe85704 100644 --- a/src/commands/to_csv.rs +++ b/src/commands/to_csv.rs @@ -42,8 +42,10 @@ pub fn to_csv(args: CommandArgs) -> Result { Ok(out .values .map(move |a| match to_string(&value_to_csv_value(&a.item)) { - Ok(x) => ReturnSuccess::value(Value::Primitive(Primitive::String(x)).tagged(name_span)), - Err(_) => Err(ShellError::maybe_labeled_error( + Ok(x) => ReturnSuccess::value( + Value::Primitive(Primitive::String(x)).simple_spanned(name_span), + ), + Err(_) => Err(ShellError::labeled_error( "Can not convert to CSV string", "can not convert piped data to CSV string", name_span, diff --git a/src/commands/to_json.rs b/src/commands/to_json.rs index eea4936d72..9b0bece427 100644 --- a/src/commands/to_json.rs +++ b/src/commands/to_json.rs @@ -48,10 +48,10 @@ pub fn to_json(args: CommandArgs) -> Result { .values .map( move |a| match serde_json::to_string(&value_to_json_value(&a)) { - Ok(x) => { - ReturnSuccess::value(Value::Primitive(Primitive::String(x)).tagged(name_span)) - } - Err(_) => Err(ShellError::maybe_labeled_error( + Ok(x) => ReturnSuccess::value( + Value::Primitive(Primitive::String(x)).simple_spanned(name_span), + ), + Err(_) => Err(ShellError::labeled_error( "Can not convert to JSON string", "can not convert piped data to JSON string", name_span, diff --git a/src/commands/to_toml.rs b/src/commands/to_toml.rs index e8eb023ca1..7ec161dc1a 100644 --- a/src/commands/to_toml.rs +++ b/src/commands/to_toml.rs @@ -42,13 +42,13 @@ pub fn to_toml(args: CommandArgs) -> Result { .map(move |a| match toml::to_string(&value_to_toml_value(&a)) { Ok(val) => { return ReturnSuccess::value( - Value::Primitive(Primitive::String(val)).tagged(name_span), + Value::Primitive(Primitive::String(val)).simple_spanned(name_span), ) } Err(err) => Err(ShellError::type_error( "Can not convert to a TOML string", - format!("{:?} - {:?}", a.type_name(), err).tagged(name_span), + format!("{:?} - {:?}", a.type_name(), err).simple_spanned(name_span), )), }) .to_output_stream()) diff --git a/src/commands/to_yaml.rs b/src/commands/to_yaml.rs index db025b10ef..6937462e74 100644 --- a/src/commands/to_yaml.rs +++ b/src/commands/to_yaml.rs @@ -46,10 +46,10 @@ pub fn to_yaml(args: CommandArgs) -> Result { .values .map( move |a| match serde_yaml::to_string(&value_to_yaml_value(&a)) { - Ok(x) => { - ReturnSuccess::value(Value::Primitive(Primitive::String(x)).tagged(name_span)) - } - Err(_) => Err(ShellError::maybe_labeled_error( + Ok(x) => ReturnSuccess::value( + Value::Primitive(Primitive::String(x)).simple_spanned(name_span), + ), + Err(_) => Err(ShellError::labeled_error( "Can not convert to YAML string", "can not convert piped data to YAML string", name_span, diff --git a/src/commands/trim.rs b/src/commands/trim.rs index 7e16b0e4b3..754a076bbd 100644 --- a/src/commands/trim.rs +++ b/src/commands/trim.rs @@ -9,7 +9,7 @@ pub fn trim(args: CommandArgs) -> Result { .values .map(move |v| { let string = String::extract(&v)?; - ReturnSuccess::value(Value::string(string.trim()).tagged(v.span())) + ReturnSuccess::value(Value::string(string.trim()).simple_spanned(v.span())) }) .to_output_stream()) } diff --git a/src/context.rs b/src/context.rs index 5d77ece2b4..377d7f468a 100644 --- a/src/context.rs +++ b/src/context.rs @@ -79,7 +79,7 @@ impl Context { crate fn run_sink( &mut self, command: Arc, - name_span: Option, + name_span: Span, args: Args, input: Vec>, ) -> Result<(), ShellError> { @@ -111,7 +111,7 @@ impl Context { crate fn run_command( &mut self, command: Arc, - name_span: Option, + name_span: Span, source_map: SourceMap, args: Args, input: InputStream, diff --git a/src/errors.rs b/src/errors.rs index daaa2c1f83..bfa5670245 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -15,14 +15,11 @@ pub enum Description { impl Description { pub fn from(value: Tagged>) -> Description { let value_span = value.span(); + let value_tag = value.tag(); match value_span { - Span { - start: 0, - end: 0, - source: None, - } => Description::Synthetic(value.item.into()), - _ => Description::Source(Tagged::from_item(value.item.into(), value_span)), + Span { start: 0, end: 0 } => Description::Synthetic(value.item.into()), + _ => Description::Source(Tagged::from_item(value.item.into(), value_tag)), } } } @@ -44,13 +41,13 @@ pub enum ArgumentError { } pub fn labelled( - span: impl Into>, + span: impl Into, heading: &'a str, span_message: &'a str, ) -> impl FnOnce(ShellError) -> ShellError + 'a { let span = span.into(); - move |_| ShellError::maybe_labeled_error(heading, span_message, span) + move |_| ShellError::labeled_error(heading, span_message, span) } #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Serialize, Deserialize)] @@ -165,7 +162,7 @@ impl ShellError { actual: Tagged { item: Some(actual), - tag: Tag { span }, + tag: Tag { span, .. }, }, } => Diagnostic::new(Severity::Error, "Type Error").with_label( Label::new_primary(span) @@ -177,7 +174,7 @@ impl ShellError { actual: Tagged { item: None, - tag: Tag { span }, + tag: Tag { span, .. }, }, } => Diagnostic::new(Severity::Error, "Type Error") .with_label(Label::new_primary(span).with_message(expected)), @@ -220,18 +217,20 @@ impl ShellError { ) } - pub fn maybe_labeled_error( + pub fn labeled_error_with_secondary( msg: impl Into, - label: impl Into, - span: Option, + primary_label: impl Into, + primary_span: Span, + secondary_label: impl Into, + secondary_span: Span, ) -> ShellError { - match span { - Some(span) => ShellError::diagnostic( - Diagnostic::new(Severity::Error, msg.into()) - .with_label(Label::new_primary(span).with_message(label.into())), - ), - None => ShellError::string(msg), - } + ShellError::diagnostic( + Diagnostic::new_error(msg.into()) + .with_label(Label::new_primary(primary_span).with_message(primary_label.into())) + .with_label( + Label::new_secondary(secondary_span).with_message(secondary_label.into()), + ), + ) } pub fn string(title: impl Into) -> ShellError { diff --git a/src/evaluate/evaluator.rs b/src/evaluate/evaluator.rs index af7ec963ba..4f7add52f7 100644 --- a/src/evaluate/evaluator.rs +++ b/src/evaluate/evaluator.rs @@ -38,14 +38,17 @@ crate fn evaluate_baseline_expr( let right = evaluate_baseline_expr(binary.right(), registry, scope, source)?; match left.compare(binary.op(), &*right) { - Ok(result) => Ok(Tagged::from_item(Value::boolean(result), expr.span())), + Ok(result) => Ok(Tagged::from_simple_spanned_item( + Value::boolean(result), + expr.span(), + )), Err((left_type, right_type)) => Err(ShellError::coerce_error( binary.left().copy_span(left_type), binary.right().copy_span(right_type), )), } } - RawExpression::Block(block) => Ok(Tagged::from_item( + RawExpression::Block(block) => Ok(Tagged::from_simple_spanned_item( Value::Block(Block::new(block.clone(), source.clone(), expr.span())), expr.span(), )), @@ -64,7 +67,7 @@ crate fn evaluate_baseline_expr( )) } Some(next) => { - item = Tagged::from_item( + item = Tagged::from_simple_spanned_item( next.clone().item, (expr.span().start, name.span().end), ) @@ -72,7 +75,10 @@ crate fn evaluate_baseline_expr( }; } - Ok(Tagged::from_item(item.item().clone(), expr.span())) + Ok(Tagged::from_simple_spanned_item( + item.item().clone(), + expr.span(), + )) } RawExpression::Boolean(_boolean) => unimplemented!(), } @@ -95,11 +101,11 @@ fn evaluate_reference( source: &Text, ) -> Result, ShellError> { match name { - hir::Variable::It(span) => Ok(Tagged::from_item(scope.it.item.clone(), span)), + hir::Variable::It(span) => Ok(scope.it.item.clone().simple_spanned(span)), hir::Variable::Other(span) => Ok(scope .vars .get(span.slice(source)) .map(|v| v.clone()) - .unwrap_or_else(|| Value::nothing().tagged(span))), + .unwrap_or_else(|| Value::nothing().simple_spanned(span))), } } diff --git a/src/object/base.rs b/src/object/base.rs index f9c5a2236b..92e1ec4c8e 100644 --- a/src/object/base.rs +++ b/src/object/base.rs @@ -168,7 +168,7 @@ impl Block { let scope = Scope::new(value.clone()); if self.expressions.len() == 0 { - return Ok(Tagged::from_item(Value::nothing(), self.span)); + return Ok(Value::nothing().simple_spanned(self.span)); } let mut last = None; @@ -227,7 +227,7 @@ impl fmt::Debug for ValueDebug<'a> { impl Tagged { crate fn tagged_type_name(&self) -> Tagged { let name = self.type_name(); - Tagged::from_item(name, self.span()) + Tagged::from_simple_spanned_item(name, self.span()) } } @@ -352,7 +352,7 @@ impl Value { } } - pub fn get_data_by_path(&'a self, span: Span, path: &str) -> Option> { + pub fn get_data_by_path(&'a self, tag: Tag, path: &str) -> Option> { let mut current = self; for p in path.split(".") { match current.get_data_by_key(p) { @@ -361,12 +361,12 @@ impl Value { } } - Some(Tagged::from_item(current, span)) + Some(Tagged::from_item(current, tag)) } pub fn insert_data_at_path( &'a self, - span: Span, + tag: Tag, path: &str, new_value: Value, ) -> Option> { @@ -384,13 +384,13 @@ impl Value { Value::Object(o) => { o.entries.insert( split_path[idx + 1].to_string(), - Tagged::from_item(new_value, span), + Tagged::from_item(new_value, tag), ); } _ => {} } - return Some(Tagged::from_item(new_obj, span)); + return Some(Tagged::from_item(new_obj, tag)); } else { match next.item { Value::Object(ref mut o) => { @@ -410,7 +410,7 @@ impl Value { pub fn replace_data_at_path( &'a self, - span: Span, + tag: Tag, path: &str, replaced_value: Value, ) -> Option> { @@ -424,8 +424,8 @@ impl Value { match current.entries.get_mut(split_path[idx]) { Some(next) => { if idx == (split_path.len() - 1) { - *next = Tagged::from_item(replaced_value, span); - return Some(Tagged::from_item(new_obj, span)); + *next = Tagged::from_item(replaced_value, tag); + return Some(Tagged::from_item(new_obj, tag)); } else { match next.item { Value::Object(ref mut o) => { @@ -601,8 +601,8 @@ impl Value { } } -crate fn select_fields(obj: &Value, fields: &[String], span: impl Into) -> Tagged { - let mut out = TaggedDictBuilder::new(span); +crate fn select_fields(obj: &Value, fields: &[String], tag: impl Into) -> Tagged { + let mut out = TaggedDictBuilder::new(tag); let descs = obj.data_descriptors(); @@ -616,8 +616,8 @@ crate fn select_fields(obj: &Value, fields: &[String], span: impl Into) -> out.into_tagged_value() } -crate fn reject_fields(obj: &Value, fields: &[String], span: impl Into) -> Tagged { - let mut out = TaggedDictBuilder::new(span); +crate fn reject_fields(obj: &Value, fields: &[String], tag: impl Into) -> Tagged { + let mut out = TaggedDictBuilder::new(tag); let descs = obj.data_descriptors(); diff --git a/src/object/config.rs b/src/object/config.rs index 15046ee313..b46c6d7014 100644 --- a/src/object/config.rs +++ b/src/object/config.rs @@ -47,7 +47,7 @@ crate fn config(span: impl Into) -> Result> trace!("config file = {}", filename.display()); let contents = fs::read_to_string(filename) - .map(|v| v.tagged(span)) + .map(|v| v.simple_spanned(span)) .map_err(|err| ShellError::string(&format!("Couldn't read config file:\n{}", err)))?; let parsed: Config = toml::from_str(&contents) diff --git a/src/object/dict.rs b/src/object/dict.rs index b7463d2417..1ce9706a10 100644 --- a/src/object/dict.rs +++ b/src/object/dict.rs @@ -102,20 +102,20 @@ impl Dictionary { } pub struct TaggedListBuilder { - span: Span, + tag: Tag, list: Vec>, } impl TaggedListBuilder { - pub fn new(span: impl Into) -> TaggedListBuilder { + pub fn new(tag: impl Into) -> TaggedListBuilder { TaggedListBuilder { - span: span.into(), + tag: tag.into(), list: vec![], } } pub fn push(&mut self, value: impl Into) { - self.list.push(value.into().tagged(self.span)); + self.list.push(value.into().tagged(self.tag)); } pub fn insert_tagged(&mut self, value: impl Into>) { @@ -123,7 +123,7 @@ impl TaggedListBuilder { } pub fn into_tagged_value(self) -> Tagged { - Value::List(self.list).tagged(self.span) + Value::List(self.list).tagged(self.tag) } } @@ -135,20 +135,20 @@ impl From for Tagged { #[derive(Debug)] pub struct TaggedDictBuilder { - span: Span, + tag: Tag, dict: IndexMap>, } impl TaggedDictBuilder { - pub fn new(span: impl Into) -> TaggedDictBuilder { + pub fn new(tag: impl Into) -> TaggedDictBuilder { TaggedDictBuilder { - span: span.into(), + tag: tag.into(), dict: IndexMap::default(), } } pub fn insert(&mut self, key: impl Into, value: impl Into) { - self.dict.insert(key.into(), value.into().tagged(self.span)); + self.dict.insert(key.into(), value.into().tagged(self.tag)); } pub fn insert_tagged(&mut self, key: impl Into, value: impl Into>) { @@ -160,7 +160,7 @@ impl TaggedDictBuilder { } pub fn into_tagged_dict(self) -> Tagged { - Dictionary { entries: self.dict }.tagged(self.span) + Dictionary { entries: self.dict }.tagged(self.tag) } } diff --git a/src/object/files.rs b/src/object/files.rs index 8cc7c878d5..541e60eb57 100644 --- a/src/object/files.rs +++ b/src/object/files.rs @@ -12,9 +12,9 @@ pub enum FileType { crate fn dir_entry_dict( filename: &std::path::Path, metadata: &std::fs::Metadata, - span: impl Into, + tag: impl Into, ) -> Result, ShellError> { - let mut dict = TaggedDictBuilder::new(span); + let mut dict = TaggedDictBuilder::new(tag); dict.insert("name", Value::string(filename.to_string_lossy())); let kind = if metadata.is_dir() { diff --git a/src/object/into.rs b/src/object/into.rs index 8e996e7551..1d2648a7ad 100644 --- a/src/object/into.rs +++ b/src/object/into.rs @@ -17,6 +17,6 @@ impl> Tagged { pub fn into_tagged_value(self) -> Tagged { let value_span = self.span(); let value = self.item.into(); - value.tagged(value_span) + value.simple_spanned(value_span) } } diff --git a/src/object/meta.rs b/src/object/meta.rs index 8fb815a67f..4881d7d000 100644 --- a/src/object/meta.rs +++ b/src/object/meta.rs @@ -5,25 +5,32 @@ use serde::Serialize; use serde_derive::Deserialize; use uuid::Uuid; -#[derive( - new, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash, Getters, -)] -#[get = "crate"] +#[derive(new, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)] pub struct Tagged { pub tag: Tag, pub item: T, } pub trait TaggedItem: Sized { - fn tagged(self, span: impl Into) -> Tagged { - Tagged::from_item(self, span.into()) + fn tagged(self, tag: impl Into) -> Tagged { + Tagged::from_item(self, tag.into()) + } + + fn simple_spanned(self, span: impl Into) -> Tagged { + Tagged::from_simple_spanned_item(self, span.into()) } // For now, this is a temporary facility. In many cases, there are other useful spans that we // could be using, such as the original source spans of JSON or Toml files, but we don't yet // have the infrastructure to make that work. fn tagged_unknown(self) -> Tagged { - Tagged::from_item(self, (0, 0)) + Tagged::from_item( + self, + Tag { + span: Span::unknown(), + origin: None, + }, + ) } } @@ -38,28 +45,44 @@ impl std::ops::Deref for Tagged { } impl Tagged { - pub fn tagged(self, span: impl Into) -> Tagged { - Tagged::from_item(self.item, span.into()) + pub fn spanned(self, span: impl Into) -> Tagged { + Tagged::from_item( + self.item, + Tag { + span: span.into(), + origin: None, + }, + ) } - pub fn from_item(item: T, span: impl Into) -> Tagged { + pub fn from_item(item: T, tag: impl Into) -> Tagged { Tagged { item, - tag: Tag { span: span.into() }, + tag: tag.into(), } } + pub fn from_simple_spanned_item(item: T, span: impl Into) -> Tagged { + Tagged::from_item( + item, + Tag { + span: span.into(), + origin: None, + }, + ) + } + pub fn map(self, input: impl FnOnce(T) -> U) -> Tagged { - let span = self.span(); + let tag = self.tag(); let mapped = input(self.item); - Tagged::from_item(mapped, span) + Tagged::from_item(mapped, tag.clone()) } crate fn copy_span(&self, output: U) -> Tagged { let span = self.span(); - Tagged::from_item(output, span) + Tagged::from_simple_spanned_item(output, span) } pub fn source(&self, source: &Text) -> Text { @@ -69,6 +92,18 @@ impl Tagged { pub fn span(&self) -> Span { self.tag.span } + + pub fn tag(&self) -> Tag { + self.tag + } + + pub fn origin(&self) -> Option { + self.tag.origin + } + + pub fn item(&self) -> &T { + &self.item + } } impl From<&Tagged> for Span { @@ -88,7 +123,6 @@ impl From> for Span { Span { start: input.offset, end: input.offset + input.fragment.len(), - source: None, } } } @@ -98,7 +132,6 @@ impl From<(nom5_locate::LocatedSpan, nom5_locate::LocatedSpan)> for Spa Span { start: input.0.offset, end: input.1.offset, - source: None, } } } @@ -108,7 +141,6 @@ impl From<(usize, usize)> for Span { Span { start: input.0, end: input.1, - source: None, } } } @@ -118,7 +150,6 @@ impl From<&std::ops::Range> for Span { Span { start: input.start, end: input.end, - source: None, } } } @@ -127,24 +158,33 @@ impl From<&std::ops::Range> for Span { Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, Hash, Getters, )] pub struct Tag { + pub origin: Option, pub span: Span, } +impl Tag { + pub fn unknown_origin(span: Span) -> Tag { + Tag { origin: None, span } + } + + pub fn unknown() -> Tag { + Tag { + origin: None, + span: Span::unknown(), + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, Hash)] pub struct Span { crate start: usize, crate end: usize, - pub source: Option, } impl From> for Span { fn from(input: Option) -> Span { match input { - None => Span { - start: 0, - end: 0, - source: None, - }, + None => Span { start: 0, end: 0 }, Some(span) => span, } } @@ -152,13 +192,10 @@ impl From> for Span { impl Span { pub fn unknown() -> Span { - Span { - start: 0, - end: 0, - source: None, - } + Span { start: 0, end: 0 } } + /* pub fn unknown_with_uuid(uuid: Uuid) -> Span { Span { start: 0, @@ -166,6 +203,7 @@ impl Span { source: Some(uuid), } } + */ pub fn is_unknown(&self) -> bool { self.start == 0 && self.end == 0 @@ -181,7 +219,6 @@ impl language_reporting::ReportingSpan for Span { Span { start, end: self.end, - source: None, } } @@ -189,7 +226,6 @@ impl language_reporting::ReportingSpan for Span { Span { start: self.start, end, - source: None, } } diff --git a/src/object/process.rs b/src/object/process.rs index c5529a46e1..2d90dba2d7 100644 --- a/src/object/process.rs +++ b/src/object/process.rs @@ -3,8 +3,8 @@ use crate::prelude::*; use itertools::join; use sysinfo::ProcessExt; -crate fn process_dict(proc: &sysinfo::Process, span: impl Into) -> Tagged { - let mut dict = TaggedDictBuilder::new(span); +crate fn process_dict(proc: &sysinfo::Process, tag: impl Into) -> Tagged { + let mut dict = TaggedDictBuilder::new(tag); let cmd = proc.cmd(); diff --git a/src/object/types.rs b/src/object/types.rs index 9e0cb65740..efa1d44bf0 100644 --- a/src/object/types.rs +++ b/src/object/types.rs @@ -21,7 +21,7 @@ pub trait ExtractType: Sized { impl ExtractType for Tagged { fn extract(value: &Tagged) -> Result, ShellError> { - Ok(T::extract(value)?.tagged(value.span())) + Ok(T::extract(value)?.simple_spanned(value.span())) } fn check(value: &'value Tagged) -> Result<&'value Tagged, ShellError> { diff --git a/src/parser/hir.rs b/src/parser/hir.rs index 41b4fbdda2..86a824e798 100644 --- a/src/parser/hir.rs +++ b/src/parser/hir.rs @@ -64,36 +64,36 @@ pub type Expression = Tagged; impl Expression { fn int(i: impl Into, span: impl Into) -> Expression { - Tagged::from_item(RawExpression::Literal(Literal::Integer(i.into())), span) + Tagged::from_simple_spanned_item(RawExpression::Literal(Literal::Integer(i.into())), span) } fn size(i: impl Into, unit: impl Into, span: impl Into) -> Expression { - Tagged::from_item( + Tagged::from_simple_spanned_item( RawExpression::Literal(Literal::Size(i.into(), unit.into())), span, ) } fn string(inner: impl Into, outer: impl Into) -> Expression { - Tagged::from_item( + Tagged::from_simple_spanned_item( RawExpression::Literal(Literal::String(inner.into())), outer.into(), ) } fn bare(span: impl Into) -> Expression { - Tagged::from_item(RawExpression::Literal(Literal::Bare), span.into()) + Tagged::from_simple_spanned_item(RawExpression::Literal(Literal::Bare), span.into()) } fn variable(inner: impl Into, outer: impl Into) -> Expression { - Tagged::from_item( + Tagged::from_simple_spanned_item( RawExpression::Variable(Variable::Other(inner.into())), outer.into(), ) } fn it_variable(inner: impl Into, outer: impl Into) -> Expression { - Tagged::from_item( + Tagged::from_simple_spanned_item( RawExpression::Variable(Variable::It(inner.into())), outer.into(), ) diff --git a/src/parser/hir/baseline_parse_tokens.rs b/src/parser/hir/baseline_parse_tokens.rs index 0bb658632d..671244db51 100644 --- a/src/parser/hir/baseline_parse_tokens.rs +++ b/src/parser/hir/baseline_parse_tokens.rs @@ -61,7 +61,7 @@ pub fn baseline_parse_next_expr( (SyntaxType::Path, token) => { return Err(ShellError::type_error( "Path", - token.type_name().tagged(token.span()), + token.type_name().simple_spanned(token.span()), )) } @@ -81,10 +81,10 @@ pub fn baseline_parse_next_expr( let second = match tokens.next() { None => { - return Err(ShellError::maybe_labeled_error( + return Err(ShellError::labeled_error( "Expected something after an operator", "operator", - Some(op.span()), + op.span(), )) } Some(token) => baseline_parse_semantic_token(token, registry, source)?, @@ -97,7 +97,7 @@ pub fn baseline_parse_next_expr( let span = (first.span().start, second.span().end); let binary = hir::Binary::new(first, op, second); let binary = hir::RawExpression::Binary(Box::new(binary)); - let binary = Tagged::from_item(binary, span); + let binary = Tagged::from_simple_spanned_item(binary, span); Ok(binary) } @@ -108,11 +108,12 @@ pub fn baseline_parse_next_expr( let path: Tagged = match first { Tagged { item: hir::RawExpression::Literal(hir::Literal::Bare), - tag: Tag { span }, + tag: Tag { span, .. }, } => { - let string = Tagged::from_item(span.slice(source).to_string(), span); + let string = + Tagged::from_simple_spanned_item(span.slice(source).to_string(), span); let path = hir::Path::new( - Tagged::from_item( + Tagged::from_simple_spanned_item( // TODO: Deal with synthetic nodes that have no representation at all in source hir::RawExpression::Variable(hir::Variable::It(Span::from((0, 0)))), (0, 0), @@ -120,15 +121,16 @@ pub fn baseline_parse_next_expr( vec![string], ); let path = hir::RawExpression::Path(Box::new(path)); - Tagged::from_item(path, first.span()) + Tagged::from_simple_spanned_item(path, first.span()) } Tagged { item: hir::RawExpression::Literal(hir::Literal::String(inner)), - tag: Tag { span }, + tag: Tag { span, .. }, } => { - let string = Tagged::from_item(inner.slice(source).to_string(), span); + let string = + Tagged::from_simple_spanned_item(inner.slice(source).to_string(), span); let path = hir::Path::new( - Tagged::from_item( + Tagged::from_simple_spanned_item( // TODO: Deal with synthetic nodes that have no representation at all in source hir::RawExpression::Variable(hir::Variable::It(Span::from((0, 0)))), (0, 0), @@ -136,14 +138,14 @@ pub fn baseline_parse_next_expr( vec![string], ); let path = hir::RawExpression::Path(Box::new(path)); - Tagged::from_item(path, first.span()) + Tagged::from_simple_spanned_item(path, first.span()) } Tagged { item: hir::RawExpression::Variable(..), .. } => first, Tagged { - tag: Tag { span }, + tag: Tag { span, .. }, item, } => { return Err(ShellError::labeled_error( @@ -156,10 +158,10 @@ pub fn baseline_parse_next_expr( let binary = hir::Binary::new(path, op, second); let binary = hir::RawExpression::Binary(Box::new(binary)); - let binary = Tagged::from_item(binary, span); + let binary = Tagged::from_simple_spanned_item(binary, span); let block = hir::RawExpression::Block(vec![binary]); - let block = Tagged::from_item(block, span); + let block = Tagged::from_simple_spanned_item(block, span); Ok(block) } @@ -204,7 +206,7 @@ pub fn baseline_parse_delimited( baseline_parse_tokens(&mut TokensIterator::new(children), registry, source)?; let expr = hir::RawExpression::Block(exprs); - Ok(Tagged::from_item(expr, token.span())) + Ok(Tagged::from_simple_spanned_item(expr, token.span())) } Delimiter::Paren => unimplemented!(), Delimiter::Square => unimplemented!(), @@ -228,7 +230,7 @@ pub fn baseline_parse_path( RawToken::Integer(_) | RawToken::Size(..) | RawToken::Variable(_) => { return Err(ShellError::type_error( "String", - token.type_name().tagged(part), + token.type_name().simple_spanned(part), )) } }, @@ -240,10 +242,10 @@ pub fn baseline_parse_path( } .to_string(); - tail.push(string.tagged(part)); + tail.push(string.simple_spanned(part)); } - Ok(hir::path(head, tail).tagged(token).into()) + Ok(hir::path(head, tail).simple_spanned(token).into()) } #[derive(Debug, new)] diff --git a/src/parser/parse/parser.rs b/src/parser/parse/parser.rs index d83fd1aef5..802acf75dc 100644 --- a/src/parser/parse/parser.rs +++ b/src/parser/parse/parser.rs @@ -77,7 +77,7 @@ pub fn raw_integer(input: NomSpan) -> IResult> { Ok(( input, - Tagged::from_item(int(num.fragment, neg), (start, end)), + Tagged::from_simple_spanned_item(int(num.fragment, neg), (start, end)), )) }) } @@ -231,7 +231,7 @@ pub fn raw_unit(input: NomSpan) -> IResult> { Ok(( input, - Tagged::from_item(Unit::from(unit.fragment), (start, end)), + Tagged::from_simple_spanned_item(Unit::from(unit.fragment), (start, end)), )) }) } @@ -1029,7 +1029,7 @@ mod tests { right: usize, ) -> TokenNode { let node = DelimitedNode::new(delimiter, children); - let spanned = Tagged::from_item(node, (left, right)); + let spanned = Tagged::from_simple_spanned_item(node, (left, right)); TokenNode::Delimited(spanned) } @@ -1038,16 +1038,16 @@ mod tests { Box::new(head), tail.into_iter().map(TokenNode::Token).collect(), ); - let spanned = Tagged::from_item(node, (left, right)); + let spanned = Tagged::from_simple_spanned_item(node, (left, right)); TokenNode::Path(spanned) } fn leaf_token(token: RawToken, left: usize, right: usize) -> TokenNode { - TokenNode::Token(Tagged::from_item(token, (left, right))) + TokenNode::Token(Tagged::from_simple_spanned_item(token, (left, right))) } fn token(token: RawToken, left: usize, right: usize) -> TokenNode { - TokenNode::Token(Tagged::from_item(token, (left, right))) + TokenNode::Token(Tagged::from_simple_spanned_item(token, (left, right))) } fn build(block: CurriedNode) -> T { diff --git a/src/parser/parse/token_tree_builder.rs b/src/parser/parse/token_tree_builder.rs index 1c3d37476c..cd56caea5a 100644 --- a/src/parser/parse/token_tree_builder.rs +++ b/src/parser/parse/token_tree_builder.rs @@ -92,7 +92,7 @@ impl TokenTreeBuilder { input: (Vec, Option), span: impl Into, ) -> TokenNode { - TokenNode::Pipeline(Tagged::from_item( + TokenNode::Pipeline(Tagged::from_simple_spanned_item( Pipeline::new(input.0, input.1.into()), span, )) @@ -111,7 +111,7 @@ impl TokenTreeBuilder { } pub fn spanned_op(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Operator(Tagged::from_item(input.into(), span.into())) + TokenNode::Operator(Tagged::from_simple_spanned_item(input.into(), span.into())) } pub fn string(input: impl Into) -> CurriedToken { @@ -128,7 +128,7 @@ impl TokenTreeBuilder { } pub fn spanned_string(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Token(Tagged::from_item( + TokenNode::Token(Tagged::from_simple_spanned_item( RawToken::String(input.into()), span.into(), )) @@ -146,7 +146,10 @@ impl TokenTreeBuilder { } pub fn spanned_bare(input: impl Into) -> TokenNode { - TokenNode::Token(Tagged::from_item(RawToken::Bare, input.into())) + TokenNode::Token(Tagged::from_simple_spanned_item( + RawToken::Bare, + input.into(), + )) } pub fn int(input: impl Into) -> CurriedToken { @@ -161,7 +164,10 @@ impl TokenTreeBuilder { } pub fn spanned_int(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Token(Token::from_item(RawToken::Integer(input.into()), span)) + TokenNode::Token(Token::from_simple_spanned_item( + RawToken::Integer(input.into()), + span, + )) } pub fn size(int: impl Into, unit: impl Into) -> CurriedToken { @@ -183,7 +189,10 @@ impl TokenTreeBuilder { ) -> TokenNode { let (int, unit) = (input.0.into(), input.1.into()); - TokenNode::Token(Tagged::from_item(RawToken::Size(int, unit), span)) + TokenNode::Token(Tagged::from_simple_spanned_item( + RawToken::Size(int, unit), + span, + )) } pub fn path(head: CurriedToken, tail: Vec) -> CurriedToken { @@ -206,7 +215,7 @@ impl TokenTreeBuilder { } pub fn spanned_path(input: (TokenNode, Vec), span: impl Into) -> TokenNode { - TokenNode::Path(Tagged::from_item( + TokenNode::Path(Tagged::from_simple_spanned_item( PathNode::new(Box::new(input.0), input.1), span, )) @@ -224,7 +233,7 @@ impl TokenTreeBuilder { } pub fn spanned_var(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Token(Tagged::from_item( + TokenNode::Token(Tagged::from_simple_spanned_item( RawToken::Variable(input.into()), span.into(), )) @@ -242,7 +251,7 @@ impl TokenTreeBuilder { } pub fn spanned_flag(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Flag(Tagged::from_item( + TokenNode::Flag(Tagged::from_simple_spanned_item( Flag::new(FlagKind::Longhand, input.into()), span.into(), )) @@ -260,7 +269,7 @@ impl TokenTreeBuilder { } pub fn spanned_shorthand(input: impl Into, span: impl Into) -> TokenNode { - TokenNode::Flag(Tagged::from_item( + TokenNode::Flag(Tagged::from_simple_spanned_item( Flag::new(FlagKind::Shorthand, input.into()), span.into(), )) @@ -306,7 +315,7 @@ impl TokenTreeBuilder { let head = input.next().unwrap(); let tail = input.collect(); - Tagged::from_item(CallNode::new(Box::new(head), tail), span) + Tagged::from_simple_spanned_item(CallNode::new(Box::new(head), tail), span) } pub fn parens(input: Vec) -> CurriedToken { @@ -324,7 +333,7 @@ impl TokenTreeBuilder { } pub fn spanned_parens(input: impl Into>, span: impl Into) -> TokenNode { - TokenNode::Delimited(Tagged::from_item( + TokenNode::Delimited(Tagged::from_simple_spanned_item( DelimitedNode::new(Delimiter::Paren, input.into()), span, )) @@ -345,7 +354,7 @@ impl TokenTreeBuilder { } pub fn spanned_square(input: impl Into>, span: impl Into) -> TokenNode { - TokenNode::Delimited(Tagged::from_item( + TokenNode::Delimited(Tagged::from_simple_spanned_item( DelimitedNode::new(Delimiter::Square, input.into()), span, )) @@ -366,7 +375,7 @@ impl TokenTreeBuilder { } pub fn spanned_brace(input: impl Into>, span: impl Into) -> TokenNode { - TokenNode::Delimited(Tagged::from_item( + TokenNode::Delimited(Tagged::from_simple_spanned_item( DelimitedNode::new(Delimiter::Brace, input.into()), span, )) diff --git a/src/parser/parse_command.rs b/src/parser/parse_command.rs index e04aa7a622..835b97dfbd 100644 --- a/src/parser/parse_command.rs +++ b/src/parser/parse_command.rs @@ -48,8 +48,8 @@ fn parse_command_head(head: &TokenNode) -> Result { TokenNode::Token(Tagged { item: RawToken::String(inner_span), - tag: Tag { span }, - }) => Ok(Tagged::from_item( + tag: Tag { span, origin: None }, + }) => Ok(Tagged::from_simple_spanned_item( hir::RawExpression::Literal(hir::Literal::String(*inner_span)), *span, )), diff --git a/src/parser/registry.rs b/src/parser/registry.rs index bc26496bef..a655f3385e 100644 --- a/src/parser/registry.rs +++ b/src/parser/registry.rs @@ -252,8 +252,10 @@ fn evaluate_args( for (name, value) in n.named.iter() { match value { hir::named::NamedValue::PresentSwitch(span) => { - results - .insert(name.clone(), Tagged::from_item(Value::boolean(true), *span)); + results.insert( + name.clone(), + Tagged::from_simple_spanned_item(Value::boolean(true), *span), + ); } hir::named::NamedValue::Value(expr) => { results.insert( diff --git a/src/plugins/add.rs b/src/plugins/add.rs index 845d0ed572..8269bdcffa 100644 --- a/src/plugins/add.rs +++ b/src/plugins/add.rs @@ -17,10 +17,10 @@ impl Add { } fn add(&self, value: Tagged) -> Result, ShellError> { - let value_span = value.span(); + let value_tag = value.tag(); match (value.item, self.value.clone()) { (obj @ Value::Object(_), Some(v)) => match &self.field { - Some(f) => match obj.insert_data_at_path(value_span, &f, v) { + Some(f) => match obj.insert_data_at_path(value_tag, &f, v) { Some(v) => return Ok(v), None => { return Err(ShellError::string( diff --git a/src/plugins/binaryview.rs b/src/plugins/binaryview.rs index fce0ed1d82..b79688b3d4 100644 --- a/src/plugins/binaryview.rs +++ b/src/plugins/binaryview.rs @@ -30,13 +30,10 @@ impl Plugin for BinaryView { fn sink(&mut self, call_info: CallInfo, input: Vec>) { for v in input { - let value_span = v.span(); + let value_origin = v.origin(); match v.item { Value::Binary(b) => { - let source = value_span - .source - .map(|x| call_info.source_map.get(&x)) - .flatten(); + let source = value_origin.map(|x| call_info.source_map.get(&x)).flatten(); let _ = view_binary(&b, source, call_info.args.has("lores")); } _ => {} diff --git a/src/plugins/edit.rs b/src/plugins/edit.rs index a9a5da1208..f0dd113f70 100644 --- a/src/plugins/edit.rs +++ b/src/plugins/edit.rs @@ -17,10 +17,10 @@ impl Edit { } fn edit(&self, value: Tagged) -> Result, ShellError> { - let value_span = value.span(); + let value_tag = value.tag(); match (value.item, self.value.clone()) { (obj @ Value::Object(_), Some(v)) => match &self.field { - Some(f) => match obj.replace_data_at_path(value_span, &f, v) { + Some(f) => match obj.replace_data_at_path(value_tag, &f, v) { Some(v) => return Ok(v), None => { return Err(ShellError::string( diff --git a/src/plugins/inc.rs b/src/plugins/inc.rs index 5ed725a875..80f42ec672 100644 --- a/src/plugins/inc.rs +++ b/src/plugins/inc.rs @@ -26,15 +26,15 @@ impl Inc { field: &Option, ) -> Result, ShellError> { match value.item { - Value::Primitive(Primitive::Int(i)) => Ok(Value::int(i + 1).tagged(value.span())), + Value::Primitive(Primitive::Int(i)) => Ok(Value::int(i + 1).tagged(value.tag())), Value::Primitive(Primitive::Bytes(b)) => { - Ok(Value::bytes(b + 1 as u64).tagged(value.span())) + Ok(Value::bytes(b + 1 as u64).tagged(value.tag())) } Value::Primitive(Primitive::String(ref s)) => { if let Ok(i) = s.parse::() { Ok(Tagged::from_item( Value::string(format!("{}", i + 1)), - value.span(), + value.tag(), )) } else if let Ok(mut ver) = semver::Version::parse(&s) { if self.major { @@ -47,7 +47,7 @@ impl Inc { } Ok(Tagged::from_item( Value::string(ver.to_string()), - value.span(), + value.tag(), )) } else { Err(ShellError::string("string could not be incremented")) @@ -55,7 +55,7 @@ impl Inc { } Value::Object(_) => match field { Some(f) => { - let replacement = match value.item.get_data_by_path(value.span(), f) { + let replacement = match value.item.get_data_by_path(value.tag(), f) { Some(result) => self.inc(result.map(|x| x.clone()), &None)?, None => { return Err(ShellError::string("inc could not find field to replace")) @@ -63,7 +63,7 @@ impl Inc { }; match value .item - .replace_data_at_path(value.span(), f, replacement.item.clone()) + .replace_data_at_path(value.tag(), f, replacement.item.clone()) { Some(v) => return Ok(v), None => { diff --git a/src/plugins/str.rs b/src/plugins/str.rs index 216b701952..7a1fcae33e 100644 --- a/src/plugins/str.rs +++ b/src/plugins/str.rs @@ -86,11 +86,11 @@ impl Str { ) -> Result, ShellError> { match value.item { Value::Primitive(Primitive::String(ref s)) => { - Ok(Tagged::from_item(self.apply(&s), value.span())) + Ok(Tagged::from_item(self.apply(&s), value.tag())) } Value::Object(_) => match field { Some(f) => { - let replacement = match value.item.get_data_by_path(value.span(), f) { + let replacement = match value.item.get_data_by_path(value.tag(), f) { Some(result) => self.strutils(result.map(|x| x.clone()), &None)?, None => { return Err(ShellError::string("str could not find field to replace")) @@ -98,7 +98,7 @@ impl Str { }; match value .item - .replace_data_at_path(value.span(), f, replacement.item.clone()) + .replace_data_at_path(value.tag(), f, replacement.item.clone()) { Some(v) => return Ok(v), None => { @@ -194,7 +194,7 @@ mod tests { use super::Str; use indexmap::IndexMap; use nu::{ - Args, CallInfo, Plugin, ReturnSuccess, SourceMap, Span, Tagged, TaggedDictBuilder, + Args, CallInfo, Plugin, ReturnSuccess, SourceMap, Span, Tag, Tagged, TaggedDictBuilder, TaggedItem, Value, }; @@ -214,28 +214,28 @@ mod tests { fn with_long_flag(&mut self, name: &str) -> &mut Self { self.flags.insert( name.to_string(), - Value::boolean(true).tagged(Span::unknown()), + Value::boolean(true).simple_spanned(Span::unknown()), ); self } fn with_parameter(&mut self, name: &str) -> &mut Self { self.positionals - .push(Value::string(name.to_string()).tagged(Span::unknown())); + .push(Value::string(name.to_string()).simple_spanned(Span::unknown())); self } - fn create(&self) -> CallInfo { + fn create(&self, name_span: Span) -> CallInfo { CallInfo { args: Args::new(Some(self.positionals.clone()), Some(self.flags.clone())), source_map: SourceMap::new(), - name_span: None, + name_span, } } } fn sample_record(key: &str, value: &str) -> Tagged { - let mut record = TaggedDictBuilder::new(Span::unknown()); + let mut record = TaggedDictBuilder::new(Tag::unknown()); record.insert(key.clone(), Value::string(value)); record.into_tagged_value() } @@ -256,7 +256,11 @@ mod tests { let mut plugin = Str::new(); assert!(plugin - .begin_filter(CallStub::new().with_long_flag("downcase").create()) + .begin_filter( + CallStub::new() + .with_long_flag("downcase") + .create(Span::unknown()) + ) .is_ok()); assert!(plugin.action.is_some()); } @@ -266,7 +270,11 @@ mod tests { let mut plugin = Str::new(); assert!(plugin - .begin_filter(CallStub::new().with_long_flag("upcase").create()) + .begin_filter( + CallStub::new() + .with_long_flag("upcase") + .create(Span::unknown()) + ) .is_ok()); assert!(plugin.action.is_some()); } @@ -276,7 +284,11 @@ mod tests { let mut plugin = Str::new(); assert!(plugin - .begin_filter(CallStub::new().with_long_flag("to-int").create()) + .begin_filter( + CallStub::new() + .with_long_flag("to-int") + .create(Span::unknown()) + ) .is_ok()); assert!(plugin.action.is_some()); } @@ -289,7 +301,7 @@ mod tests { .begin_filter( CallStub::new() .with_parameter("package.description") - .create() + .create(Span::unknown()) ) .is_ok()); @@ -306,7 +318,7 @@ mod tests { .with_long_flag("upcase") .with_long_flag("downcase") .with_long_flag("to-int") - .create(), + .create(Span::unknown()), ) .is_err()); assert_eq!(plugin.error, Some("can only apply one".to_string())); @@ -342,7 +354,7 @@ mod tests { CallStub::new() .with_long_flag("upcase") .with_parameter("name") - .create() + .create(Span::unknown()) ) .is_ok()); @@ -370,7 +382,7 @@ mod tests { CallStub::new() .with_long_flag("downcase") .with_parameter("name") - .create() + .create(Span::unknown()) ) .is_ok()); @@ -398,7 +410,7 @@ mod tests { CallStub::new() .with_long_flag("to-int") .with_parameter("Nu_birthday") - .create() + .create(Span::unknown()) ) .is_ok()); diff --git a/src/plugins/sum.rs b/src/plugins/sum.rs index f3f71be86c..050e39dacf 100644 --- a/src/plugins/sum.rs +++ b/src/plugins/sum.rs @@ -18,10 +18,11 @@ impl Sum { match self.total { Some(Tagged { item: Value::Primitive(Primitive::Int(j)), - tag: Tag { span }, + tag: Tag { span, .. }, }) => { //TODO: handle overflow - self.total = Some(Tagged::from_item(Value::int(i + j), span)); + self.total = + Some(Tagged::from_simple_spanned_item(Value::int(i + j), span)); Ok(()) } None => { @@ -37,10 +38,11 @@ impl Sum { match self.total { Some(Tagged { item: Value::Primitive(Primitive::Bytes(j)), - tag: Tag { span }, + tag: Tag { span, .. }, }) => { //TODO: handle overflow - self.total = Some(Tagged::from_item(Value::bytes(b + j), span)); + self.total = + Some(Tagged::from_simple_spanned_item(Value::bytes(b + j), span)); Ok(()) } None => { diff --git a/src/plugins/sys.rs b/src/plugins/sys.rs index 515fe25abb..9f97383019 100644 --- a/src/plugins/sys.rs +++ b/src/plugins/sys.rs @@ -6,7 +6,7 @@ use heim::{disk, memory}; use indexmap::IndexMap; use nu::{ serve_plugin, CallInfo, CommandConfig, Plugin, Primitive, ReturnSuccess, ReturnValue, - ShellError, Span, Tagged, TaggedDictBuilder, Value, OF64, + ShellError, Tag, Tagged, TaggedDictBuilder, Value, OF64, }; use std::ffi::OsStr; @@ -19,9 +19,9 @@ impl Sys { //TODO: add more error checking -async fn cpu(span: Span) -> Option> { +async fn cpu(tag: Tag) -> Option> { if let (Ok(num_cpu), Ok(cpu_speed)) = (sys_info::cpu_num(), sys_info::cpu_speed()) { - let mut cpu_idx = TaggedDictBuilder::new(span); + let mut cpu_idx = TaggedDictBuilder::new(tag); cpu_idx.insert("cores", Primitive::Int(num_cpu as i64)); cpu_idx.insert("speed", Primitive::Int(cpu_speed as i64)); Some(cpu_idx.into_tagged_value()) @@ -30,8 +30,8 @@ async fn cpu(span: Span) -> Option> { } } -async fn mem(span: Span) -> Tagged { - let mut dict = TaggedDictBuilder::new(span); +async fn mem(tag: Tag) -> Tagged { + let mut dict = TaggedDictBuilder::new(tag); if let Ok(memory) = memory::memory().await { dict.insert("total", Value::bytes(memory.total().get())); @@ -45,8 +45,8 @@ async fn mem(span: Span) -> Tagged { dict.into_tagged_value() } -async fn host(span: Span) -> Tagged { - let mut dict = TaggedDictBuilder::new(span); +async fn host(tag: Tag) -> Tagged { + let mut dict = TaggedDictBuilder::new(tag); // OS if let Ok(platform) = heim::host::platform().await { @@ -58,7 +58,7 @@ async fn host(span: Span) -> Tagged { // Uptime if let Ok(uptime) = heim::host::uptime().await { - let mut uptime_dict = TaggedDictBuilder::new(span); + let mut uptime_dict = TaggedDictBuilder::new(tag); let uptime = uptime.get().round() as i64; let days = uptime / (60 * 60 * 24); @@ -79,7 +79,7 @@ async fn host(span: Span) -> Tagged { let mut user_vec = vec![]; while let Some(user) = users.next().await { if let Ok(user) = user { - user_vec.push(Tagged::from_item(Value::string(user.username()), span)); + user_vec.push(Tagged::from_item(Value::string(user.username()), tag)); } } let user_list = Value::List(user_vec); @@ -88,12 +88,12 @@ async fn host(span: Span) -> Tagged { dict.into_tagged_value() } -async fn disks(span: Span) -> Value { +async fn disks(tag: Tag) -> Value { let mut output = vec![]; let mut partitions = disk::partitions_physical(); while let Some(part) = partitions.next().await { if let Ok(part) = part { - let mut dict = TaggedDictBuilder::new(span); + let mut dict = TaggedDictBuilder::new(tag); dict.insert( "device", Value::string( @@ -117,14 +117,14 @@ async fn disks(span: Span) -> Value { Value::List(output) } -async fn temp(span: Span) -> Value { +async fn temp(tag: Tag) -> Value { use sysinfo::{ComponentExt, RefreshKind, SystemExt}; let system = sysinfo::System::new_with_specifics(RefreshKind::new().with_system()); let components_list = system.get_components_list(); if components_list.len() > 0 { let mut v: Vec> = vec![]; for component in components_list { - let mut component_idx = TaggedDictBuilder::new(span); + let mut component_idx = TaggedDictBuilder::new(tag); component_idx.insert("name", Primitive::String(component.get_label().to_string())); component_idx.insert( "temp", @@ -145,7 +145,7 @@ async fn temp(span: Span) -> Value { } } -async fn net(span: Span) -> Tagged { +async fn net(tag: Tag) -> Tagged { use sysinfo::{NetworkExt, RefreshKind, SystemExt}; let system = sysinfo::System::new_with_specifics(RefreshKind::new().with_network()); @@ -153,23 +153,23 @@ async fn net(span: Span) -> Tagged { let incoming = network.get_income(); let outgoing = network.get_outcome(); - let mut network_idx = TaggedDictBuilder::new(span); + let mut network_idx = TaggedDictBuilder::new(tag); network_idx.insert("incoming", Value::bytes(incoming)); network_idx.insert("outgoing", Value::bytes(outgoing)); network_idx.into_tagged_value() } -async fn sysinfo(span: Span) -> Vec> { - let mut sysinfo = TaggedDictBuilder::new(span); +async fn sysinfo(tag: Tag) -> Vec> { + let mut sysinfo = TaggedDictBuilder::new(tag); - sysinfo.insert_tagged("host", host(span).await); - if let Some(cpu) = cpu(span).await { + sysinfo.insert_tagged("host", host(tag).await); + if let Some(cpu) = cpu(tag).await { sysinfo.insert_tagged("cpu", cpu); } - sysinfo.insert("disks", disks(span).await); - sysinfo.insert_tagged("mem", mem(span).await); - sysinfo.insert("temp", temp(span).await); - sysinfo.insert_tagged("net", net(span).await); + sysinfo.insert("disks", disks(tag).await); + sysinfo.insert_tagged("mem", mem(tag).await); + sysinfo.insert("temp", temp(tag).await); + sysinfo.insert_tagged("net", net(tag).await); vec![sysinfo.into_tagged_value()] } @@ -186,12 +186,10 @@ impl Plugin for Sys { }) } fn begin_filter(&mut self, callinfo: CallInfo) -> Result, ShellError> { - Ok(block_on(sysinfo( - callinfo.name_span.unwrap_or_else(|| Span::unknown()), - )) - .into_iter() - .map(|x| ReturnSuccess::value(x)) - .collect()) + Ok(block_on(sysinfo(Tag::unknown_origin(callinfo.name_span))) + .into_iter() + .map(|x| ReturnSuccess::value(x)) + .collect()) } fn filter(&mut self, _: Tagged) -> Result, ShellError> { diff --git a/src/plugins/textview.rs b/src/plugins/textview.rs index 79f524f987..29ccf20608 100644 --- a/src/plugins/textview.rs +++ b/src/plugins/textview.rs @@ -210,10 +210,10 @@ fn scroll_view(s: &str) { } fn view_text_value(value: &Tagged, source_map: &SourceMap) { - let value_span = value.span(); + let value_origin = value.origin(); match value.item { Value::Primitive(Primitive::String(ref s)) => { - let source = value_span.source.map(|x| source_map.get(&x)).flatten(); + let source = value_origin.map(|x| source_map.get(&x)).flatten(); if let Some(source) = source { let extension: Option = match source {