Merge pull request #234 from jonathandturner/tagged

Add Tagged, a new metadata holder
This commit is contained in:
Jonathan Turner 2019-08-01 15:52:13 +12:00 committed by GitHub
commit 37767b8882
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
81 changed files with 806 additions and 898 deletions

View file

@ -144,6 +144,7 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
| skip amount | Skip a number of rows | | skip amount | Skip a number of rows |
| first amount | Show only the first number of rows | | first amount | Show only the first number of rows |
| str (field) | Apply string function. Optional use the field of a table | | str (field) | Apply string function. Optional use the field of a table |
| tags | Read the tags (metadata) for values |
| to-array | Collapse rows into a single list | | to-array | Collapse rows into a single list |
| to-json | Convert table into .json text | | to-json | Convert table into .json text |
| to-toml | Convert table into .toml text | | to-toml | Convert table into .toml text |

View file

@ -12,7 +12,6 @@ crate use crate::errors::ShellError;
use crate::evaluate::Scope; use crate::evaluate::Scope;
use crate::git::current_branch; use crate::git::current_branch;
use crate::object::Value; use crate::object::Value;
use crate::parser::parse::span::Spanned;
use crate::parser::registry; use crate::parser::registry;
use crate::parser::registry::CommandConfig; use crate::parser::registry::CommandConfig;
use crate::parser::{Pipeline, PipelineElement, TokenNode}; use crate::parser::{Pipeline, PipelineElement, TokenNode};
@ -176,6 +175,7 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
command("to-toml", Box::new(to_toml::to_toml)), command("to-toml", Box::new(to_toml::to_toml)),
command("to-yaml", Box::new(to_yaml::to_yaml)), command("to-yaml", Box::new(to_yaml::to_yaml)),
command("sort-by", Box::new(sort_by::sort_by)), command("sort-by", Box::new(sort_by::sort_by)),
command("tags", Box::new(tags::tags)),
Arc::new(Remove), Arc::new(Remove),
Arc::new(Copycp), Arc::new(Copycp),
Arc::new(Open), Arc::new(Open),
@ -386,7 +386,7 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
} }
(Some(ClassifiedCommand::Sink(left)), None) => { (Some(ClassifiedCommand::Sink(left)), None) => {
let input_vec: Vec<Spanned<Value>> = input.objects.into_vec().await; let input_vec: Vec<Tagged<Value>> = input.objects.into_vec().await;
if let Err(err) = left.run(ctx, input_vec) { if let Err(err) = left.run(ctx, input_vec) {
return LineResult::Error(line.clone(), err); return LineResult::Error(line.clone(), err);
} }
@ -497,7 +497,6 @@ fn classify_command(
Ok(ClassifiedCommand::Internal(InternalCommand { Ok(ClassifiedCommand::Internal(InternalCommand {
command, command,
name_span: Some(head.span().clone()), name_span: Some(head.span().clone()),
source_map: context.source_map.clone(),
args, args,
})) }))
} }
@ -516,13 +515,13 @@ fn classify_command(
})) }))
} }
false => { false => {
let arg_list_strings: Vec<Spanned<String>> = match call.children() { let arg_list_strings: Vec<Tagged<String>> = match call.children() {
//Some(args) => args.iter().map(|i| i.as_external_arg(source)).collect(), //Some(args) => args.iter().map(|i| i.as_external_arg(source)).collect(),
Some(args) => args Some(args) => args
.iter() .iter()
.filter_map(|i| match i { .filter_map(|i| match i {
TokenNode::Whitespace(_) => None, TokenNode::Whitespace(_) => None,
other => Some(Spanned::from_item( other => Some(Tagged::from_item(
other.as_external_arg(source), other.as_external_arg(source),
other.span(), other.span(),
)), )),

View file

@ -34,6 +34,7 @@ crate mod sort_by;
crate mod split_column; crate mod split_column;
crate mod split_row; crate mod split_row;
crate mod table; crate mod table;
crate mod tags;
crate mod to_array; crate mod to_array;
crate mod to_csv; crate mod to_csv;
crate mod to_json; crate mod to_json;

View file

@ -5,7 +5,7 @@ use crate::prelude::*;
pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> { pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> {
if args.input.len() > 0 { if args.input.len() > 0 {
if let Spanned { if let Tagged {
item: Value::Binary(_), item: Value::Binary(_),
.. ..
} = args.input[0] } = args.input[0]
@ -28,7 +28,7 @@ pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> {
Ok(()) Ok(())
} }
fn equal_shapes(input: &Vec<Spanned<Value>>) -> bool { fn equal_shapes(input: &Vec<Tagged<Value>>) -> bool {
let mut items = input.iter(); let mut items = input.iter();
let item = match items.next() { let item = match items.next() {
@ -47,11 +47,11 @@ fn equal_shapes(input: &Vec<Spanned<Value>>) -> bool {
true true
} }
fn is_single_text_value(input: &Vec<Spanned<Value>>) -> bool { fn is_single_text_value(input: &Vec<Tagged<Value>>) -> bool {
if input.len() != 1 { if input.len() != 1 {
return false; return false;
} }
if let Spanned { if let Tagged {
item: Value::Primitive(Primitive::String(_)), item: Value::Primitive(Primitive::String(_)),
.. ..
} = input[0] } = input[0]

View file

@ -25,7 +25,7 @@ pub fn cd(args: CommandArgs) -> Result<OutputStream, ShellError> {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"Can not change to directory", "Can not change to directory",
"directory not found", "directory not found",
v.span.clone(), v.span().clone(),
)); ));
} }
} }
@ -40,7 +40,7 @@ pub fn cd(args: CommandArgs) -> Result<OutputStream, ShellError> {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"Can not change to directory", "Can not change to directory",
"directory not found", "directory not found",
args.nth(0).unwrap().span.clone(), args.nth(0).unwrap().span().clone(),
)); ));
} else { } else {
return Err(ShellError::string("Can not change to directory")); return Err(ShellError::string("Can not change to directory"));

View file

@ -1,6 +1,5 @@
use crate::commands::command::Sink; use crate::commands::command::Sink;
use crate::context::SourceMap; use crate::parser::{registry::Args, TokenNode};
use crate::parser::{registry::Args, Span, Spanned, TokenNode};
use crate::prelude::*; use crate::prelude::*;
use bytes::{BufMut, BytesMut}; use bytes::{BufMut, BytesMut};
use futures::stream::StreamExt; use futures::stream::StreamExt;
@ -105,11 +104,7 @@ crate struct SinkCommand {
} }
impl SinkCommand { impl SinkCommand {
crate fn run( crate fn run(self, context: &mut Context, input: Vec<Tagged<Value>>) -> Result<(), ShellError> {
self,
context: &mut Context,
input: Vec<Spanned<Value>>,
) -> Result<(), ShellError> {
context.run_sink(self.command, self.name_span.clone(), self.args, input) context.run_sink(self.command, self.name_span.clone(), self.args, input)
} }
} }
@ -117,7 +112,6 @@ impl SinkCommand {
crate struct InternalCommand { crate struct InternalCommand {
crate command: Arc<dyn Command>, crate command: Arc<dyn Command>,
crate name_span: Option<Span>, crate name_span: Option<Span>,
crate source_map: SourceMap,
crate args: Args, crate args: Args,
} }
@ -139,7 +133,7 @@ impl InternalCommand {
let result = context.run_command( let result = context.run_command(
self.command, self.command,
self.name_span.clone(), self.name_span.clone(),
self.source_map, context.source_map.clone(),
self.args, self.args,
objects, objects,
)?; )?;
@ -173,7 +167,7 @@ crate struct ExternalCommand {
crate name: String, crate name: String,
#[allow(unused)] #[allow(unused)]
crate name_span: Option<Span>, crate name_span: Option<Span>,
crate args: Vec<Spanned<String>>, crate args: Vec<Tagged<String>>,
} }
crate enum StreamNext { crate enum StreamNext {
@ -190,7 +184,7 @@ impl ExternalCommand {
stream_next: StreamNext, stream_next: StreamNext,
) -> Result<ClassifiedInputStream, ShellError> { ) -> Result<ClassifiedInputStream, ShellError> {
let stdin = input.stdin; let stdin = input.stdin;
let inputs: Vec<Spanned<Value>> = input.objects.into_vec().await; let inputs: Vec<Tagged<Value>> = input.objects.into_vec().await;
let name_span = self.name_span.clone(); let name_span = self.name_span.clone();
trace!(target: "nu::run::external", "-> {}", self.name); trace!(target: "nu::run::external", "-> {}", self.name);
@ -215,7 +209,7 @@ impl ExternalCommand {
let mut span = None; let mut span = None;
for arg in &self.args { for arg in &self.args {
if arg.item.contains("$it") { if arg.item.contains("$it") {
span = Some(arg.span); span = Some(arg.span());
} }
} }
if let Some(span) = span { if let Some(span) = span {
@ -260,7 +254,7 @@ impl ExternalCommand {
let mut span = None; let mut span = None;
for arg in &self.args { for arg in &self.args {
if arg.item.contains("$it") { if arg.item.contains("$it") {
span = Some(arg.span); span = Some(arg.span());
} }
} }
return Err(ShellError::maybe_labeled_error( return Err(ShellError::maybe_labeled_error(
@ -322,10 +316,9 @@ impl ExternalCommand {
let stdout = popen.stdout.take().unwrap(); let stdout = popen.stdout.take().unwrap();
let file = futures::io::AllowStdIo::new(stdout); let file = futures::io::AllowStdIo::new(stdout);
let stream = Framed::new(file, LinesCodec {}); let stream = Framed::new(file, LinesCodec {});
let stream = let stream = stream.map(move |line| Value::string(line.unwrap()).tagged(name_span));
stream.map(move |line| Value::string(line.unwrap()).spanned(name_span));
Ok(ClassifiedInputStream::from_input_stream( Ok(ClassifiedInputStream::from_input_stream(
stream.boxed() as BoxStream<'static, Spanned<Value>> stream.boxed() as BoxStream<'static, Tagged<Value>>
)) ))
} }
} }

View file

@ -2,10 +2,7 @@ use crate::context::SourceMap;
use crate::context::SpanSource; use crate::context::SpanSource;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::Value; use crate::object::Value;
use crate::parser::{ use crate::parser::registry::{self, Args};
registry::{self, Args},
Span, Spanned,
};
use crate::prelude::*; use crate::prelude::*;
use getset::Getters; use getset::Getters;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -29,15 +26,15 @@ pub struct CommandArgs {
} }
impl CommandArgs { impl CommandArgs {
pub fn nth(&self, pos: usize) -> Option<&Spanned<Value>> { pub fn nth(&self, pos: usize) -> Option<&Tagged<Value>> {
self.call_info.args.nth(pos) self.call_info.args.nth(pos)
} }
pub fn positional_iter(&self) -> impl Iterator<Item = &Spanned<Value>> { pub fn positional_iter(&self) -> impl Iterator<Item = &Tagged<Value>> {
self.call_info.args.positional_iter() self.call_info.args.positional_iter()
} }
pub fn expect_nth(&self, pos: usize) -> Result<&Spanned<Value>, ShellError> { pub fn expect_nth(&self, pos: usize) -> Result<&Tagged<Value>, ShellError> {
self.call_info.args.expect_nth(pos) self.call_info.args.expect_nth(pos)
} }
@ -45,7 +42,7 @@ impl CommandArgs {
self.call_info.args.len() self.call_info.args.len()
} }
pub fn get(&self, name: &str) -> Option<&Spanned<Value>> { pub fn get(&self, name: &str) -> Option<&Tagged<Value>> {
self.call_info.args.get(name) self.call_info.args.get(name)
} }
@ -58,7 +55,7 @@ impl CommandArgs {
pub struct SinkCommandArgs { pub struct SinkCommandArgs {
pub ctx: Context, pub ctx: Context,
pub call_info: CallInfo, pub call_info: CallInfo,
pub input: Vec<Spanned<Value>>, pub input: Vec<Tagged<Value>>,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@ -70,14 +67,14 @@ pub enum CommandAction {
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub enum ReturnSuccess { pub enum ReturnSuccess {
Value(Spanned<Value>), Value(Tagged<Value>),
Action(CommandAction), Action(CommandAction),
} }
pub type ReturnValue = Result<ReturnSuccess, ShellError>; pub type ReturnValue = Result<ReturnSuccess, ShellError>;
impl From<Spanned<Value>> for ReturnValue { impl From<Tagged<Value>> for ReturnValue {
fn from(input: Spanned<Value>) -> ReturnValue { fn from(input: Tagged<Value>) -> ReturnValue {
Ok(ReturnSuccess::Value(input)) Ok(ReturnSuccess::Value(input))
} }
} }
@ -87,7 +84,7 @@ impl ReturnSuccess {
Ok(ReturnSuccess::Action(CommandAction::ChangePath(path))) Ok(ReturnSuccess::Action(CommandAction::ChangePath(path)))
} }
pub fn value(input: impl Into<Spanned<Value>>) -> ReturnValue { pub fn value(input: impl Into<Tagged<Value>>) -> ReturnValue {
Ok(ReturnSuccess::Value(input.into())) Ok(ReturnSuccess::Value(input.into()))
} }
@ -96,7 +93,7 @@ impl ReturnSuccess {
} }
pub fn spanned_value(input: Value, span: Span) -> ReturnValue { pub fn spanned_value(input: Value, span: Span) -> ReturnValue {
Ok(ReturnSuccess::Value(Spanned::from_item(input, span))) Ok(ReturnSuccess::Value(Tagged::from_item(input, span)))
} }
} }

View file

@ -62,7 +62,7 @@ pub fn config(args: CommandArgs) -> Result<OutputStream, ShellError> {
config::write_config(&result)?; config::write_config(&result)?;
return Ok( return Ok(
stream![Spanned::from_item(Value::Object(result.into()), v.span())] stream![Tagged::from_item(Value::Object(result.into()), v.span())]
.from_input_stream(), .from_input_stream(),
); );
} }
@ -74,7 +74,7 @@ pub fn config(args: CommandArgs) -> Result<OutputStream, ShellError> {
config::write_config(&result)?; config::write_config(&result)?;
return Ok( return Ok(
stream![Spanned::from_item(Value::Object(result.into()), c.span())].from_input_stream(), stream![Tagged::from_item(Value::Object(result.into()), c.span())].from_input_stream(),
); );
} }
@ -90,12 +90,12 @@ pub fn config(args: CommandArgs) -> Result<OutputStream, ShellError> {
))); )));
} }
let obj = VecDeque::from_iter(vec![Value::Object(result.into()).spanned(v)]); let obj = VecDeque::from_iter(vec![Value::Object(result.into()).tagged(v)]);
return Ok(obj.from_input_stream()); return Ok(obj.from_input_stream());
} }
if args.len() == 0 { if args.len() == 0 {
return Ok(vec![Value::Object(result.into()).spanned(args.call_info.name_span)].into()); return Ok(vec![Value::Object(result.into()).tagged(args.call_info.name_span)].into());
} }
Err(ShellError::string(format!("Unimplemented"))) Err(ShellError::string(format!("Unimplemented")))

View file

@ -1,6 +1,5 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{Dictionary, Value}; use crate::object::{Dictionary, Value};
use crate::parser::Spanned;
use crate::prelude::*; use crate::prelude::*;
use chrono::{DateTime, Local, Utc}; use chrono::{DateTime, Local, Utc};
@ -35,7 +34,7 @@ impl Command for Date {
} }
} }
pub fn date_to_value<T: TimeZone>(dt: DateTime<T>, span: Span) -> Spanned<Value> pub fn date_to_value<T: TimeZone>(dt: DateTime<T>, span: Span) -> Tagged<Value>
where where
T::Offset: Display, T::Offset: Display,
{ {
@ -43,60 +42,36 @@ where
indexmap.insert( indexmap.insert(
"year".to_string(), "year".to_string(),
Spanned { Tagged::from_item(Value::int(dt.year()), span),
item: Value::int(dt.year()),
span,
},
); );
indexmap.insert( indexmap.insert(
"month".to_string(), "month".to_string(),
Spanned { Tagged::from_item(Value::int(dt.month()), span),
item: Value::int(dt.month()),
span,
},
); );
indexmap.insert( indexmap.insert(
"day".to_string(), "day".to_string(),
Spanned { Tagged::from_item(Value::int(dt.day()), span),
item: Value::int(dt.day()),
span,
},
); );
indexmap.insert( indexmap.insert(
"hour".to_string(), "hour".to_string(),
Spanned { Tagged::from_item(Value::int(dt.hour()), span),
item: Value::int(dt.hour()),
span,
},
); );
indexmap.insert( indexmap.insert(
"minute".to_string(), "minute".to_string(),
Spanned { Tagged::from_item(Value::int(dt.minute()), span),
item: Value::int(dt.minute()),
span,
},
); );
indexmap.insert( indexmap.insert(
"second".to_string(), "second".to_string(),
Spanned { Tagged::from_item(Value::int(dt.second()), span),
item: Value::int(dt.second()),
span,
},
); );
let tz = dt.offset(); let tz = dt.offset();
indexmap.insert( indexmap.insert(
"timezone".to_string(), "timezone".to_string(),
Spanned { Tagged::from_item(Value::string(format!("{}", tz)), span),
item: Value::string(format!("{}", tz)),
span,
},
); );
Spanned { Tagged::from_item(Value::Object(Dictionary::from(indexmap)), span)
item: Value::Object(Dictionary::from(indexmap)),
span,
}
} }
pub fn date(args: CommandArgs) -> Result<OutputStream, ShellError> { pub fn date(args: CommandArgs) -> Result<OutputStream, ShellError> {

View file

@ -20,7 +20,7 @@ pub fn first(args: CommandArgs) -> Result<OutputStream, ShellError> {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"Value is not a number", "Value is not a number",
"expected integer", "expected integer",
args.expect_nth(0)?.span, args.expect_nth(0)?.span(),
)) ))
} }
}; };

View file

@ -1,12 +1,11 @@
use crate::object::{Primitive, SpannedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
use csv::ReaderBuilder; use csv::ReaderBuilder;
pub fn from_csv_string_to_value( pub fn from_csv_string_to_value(
s: String, s: String,
span: impl Into<Span>, span: impl Into<Span>,
) -> Result<Spanned<Value>, Box<dyn std::error::Error>> { ) -> Result<Tagged<Value>, Box<dyn std::error::Error>> {
let mut reader = ReaderBuilder::new() let mut reader = ReaderBuilder::new()
.has_headers(false) .has_headers(false)
.from_reader(s.as_bytes()); .from_reader(s.as_bytes());
@ -28,25 +27,22 @@ pub fn from_csv_string_to_value(
if let Some(row_values) = iter.next() { if let Some(row_values) = iter.next() {
let row_values = row_values?; let row_values = row_values?;
let mut row = SpannedDictBuilder::new(span); let mut row = TaggedDictBuilder::new(span);
for (idx, entry) in row_values.iter().enumerate() { for (idx, entry) in row_values.iter().enumerate() {
row.insert_spanned( row.insert_tagged(
fields.get(idx).unwrap(), fields.get(idx).unwrap(),
Value::Primitive(Primitive::String(String::from(entry))).spanned(span), Value::Primitive(Primitive::String(String::from(entry))).tagged(span),
); );
} }
rows.push(row.into_spanned_value()); rows.push(row.into_tagged_value());
} else { } else {
break; break;
} }
} }
Ok(Spanned { Ok(Tagged::from_item(Value::List(rows), span))
item: Value::List(rows),
span,
})
} }
pub fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> { pub fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
@ -55,20 +51,25 @@ pub fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(out Ok(out
.values .values
.map(move |a| match a.item { .map(move |a| {
Value::Primitive(Primitive::String(s)) => match from_csv_string_to_value(s, span) { let value_span = a.span();
Ok(x) => ReturnSuccess::value(x.spanned(a.span)), match a.item {
Err(_) => Err(ShellError::maybe_labeled_error( Value::Primitive(Primitive::String(s)) => {
"Could not parse as CSV", match from_csv_string_to_value(s, value_span) {
"piped data failed CSV parse", Ok(x) => ReturnSuccess::value(x),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as CSV",
"piped data failed CSV parse",
span,
)),
}
}
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span, span,
)), )),
}, }
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
}) })
.to_output_stream()) .to_output_stream())
} }

View file

@ -1,38 +1,38 @@
use crate::object::{Primitive, SpannedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
use std::collections::HashMap; use std::collections::HashMap;
fn convert_ini_second_to_nu_value( fn convert_ini_second_to_nu_value(
v: &HashMap<String, String>, v: &HashMap<String, String>,
span: impl Into<Span>, span: impl Into<Span>,
) -> Spanned<Value> { ) -> Tagged<Value> {
let mut second = SpannedDictBuilder::new(span); let mut second = TaggedDictBuilder::new(span);
for (key, value) in v.into_iter() { for (key, value) in v.into_iter() {
second.insert(key.clone(), Primitive::String(value.clone())); second.insert(key.clone(), Primitive::String(value.clone()));
} }
second.into_spanned_value() second.into_tagged_value()
} }
fn convert_ini_top_to_nu_value( fn convert_ini_top_to_nu_value(
v: &HashMap<String, HashMap<String, String>>, v: &HashMap<String, HashMap<String, String>>,
span: impl Into<Span>, span: impl Into<Span>,
) -> Spanned<Value> { ) -> Tagged<Value> {
let span = span.into(); let span = span.into();
let mut top_level = SpannedDictBuilder::new(span); let mut top_level = TaggedDictBuilder::new(span);
for (key, value) in v.iter() { for (key, value) in v.iter() {
top_level.insert_spanned(key.clone(), convert_ini_second_to_nu_value(value, span)); top_level.insert_tagged(key.clone(), convert_ini_second_to_nu_value(value, span));
} }
top_level.into_spanned_value() top_level.into_tagged_value()
} }
pub fn from_ini_string_to_value( pub fn from_ini_string_to_value(
s: String, s: String,
span: impl Into<Span>, span: impl Into<Span>,
) -> Result<Spanned<Value>, Box<dyn std::error::Error>> { ) -> Result<Tagged<Value>, Box<dyn std::error::Error>> {
let v: HashMap<String, HashMap<String, String>> = serde_ini::from_str(&s)?; let v: HashMap<String, HashMap<String, String>> = serde_ini::from_str(&s)?;
Ok(convert_ini_top_to_nu_value(&v, span)) Ok(convert_ini_top_to_nu_value(&v, span))
} }
@ -42,20 +42,25 @@ pub fn from_ini(args: CommandArgs) -> Result<OutputStream, ShellError> {
let span = args.call_info.name_span; let span = args.call_info.name_span;
Ok(out Ok(out
.values .values
.map(move |a| match a.item { .map(move |a| {
Value::Primitive(Primitive::String(s)) => match from_ini_string_to_value(s, span) { let value_span = a.span();
Ok(x) => ReturnSuccess::value(x.spanned(a.span)), match a.item {
Err(_) => Err(ShellError::maybe_labeled_error( Value::Primitive(Primitive::String(s)) => {
"Could not parse as INI", match from_ini_string_to_value(s, value_span) {
"piped data failed INI parse", Ok(x) => ReturnSuccess::value(x),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as INI",
"piped data failed INI parse",
span,
)),
}
}
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span, span,
)), )),
}, }
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
}) })
.to_output_stream()) .to_output_stream())
} }

View file

@ -1,36 +1,36 @@
use crate::object::base::OF64; use crate::object::base::OF64;
use crate::object::{Primitive, SpannedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
fn convert_json_value_to_nu_value(v: &serde_hjson::Value, span: impl Into<Span>) -> Spanned<Value> { fn convert_json_value_to_nu_value(v: &serde_hjson::Value, span: impl Into<Span>) -> Tagged<Value> {
let span = span.into(); let span = span.into();
match v { match v {
serde_hjson::Value::Null => { serde_hjson::Value::Null => {
Value::Primitive(Primitive::String(String::from(""))).spanned(span) Value::Primitive(Primitive::String(String::from(""))).tagged(span)
} }
serde_hjson::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).spanned(span), serde_hjson::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(span),
serde_hjson::Value::F64(n) => { serde_hjson::Value::F64(n) => {
Value::Primitive(Primitive::Float(OF64::from(*n))).spanned(span) Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(span)
} }
serde_hjson::Value::U64(n) => Value::Primitive(Primitive::Int(*n as i64)).spanned(span), 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)).spanned(span), serde_hjson::Value::I64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(span),
serde_hjson::Value::String(s) => { serde_hjson::Value::String(s) => {
Value::Primitive(Primitive::String(String::from(s))).spanned(span) Value::Primitive(Primitive::String(String::from(s))).tagged(span)
} }
serde_hjson::Value::Array(a) => Value::List( serde_hjson::Value::Array(a) => Value::List(
a.iter() a.iter()
.map(|x| convert_json_value_to_nu_value(x, span)) .map(|x| convert_json_value_to_nu_value(x, span))
.collect(), .collect(),
) )
.spanned(span), .tagged(span),
serde_hjson::Value::Object(o) => { serde_hjson::Value::Object(o) => {
let mut collected = SpannedDictBuilder::new(span); let mut collected = TaggedDictBuilder::new(span);
for (k, v) in o.iter() { for (k, v) in o.iter() {
collected.insert_spanned(k.clone(), convert_json_value_to_nu_value(v, span)); collected.insert_tagged(k.clone(), convert_json_value_to_nu_value(v, span));
} }
collected.into_spanned_value() collected.into_tagged_value()
} }
} }
} }
@ -38,7 +38,7 @@ fn convert_json_value_to_nu_value(v: &serde_hjson::Value, span: impl Into<Span>)
pub fn from_json_string_to_value( pub fn from_json_string_to_value(
s: String, s: String,
span: impl Into<Span>, span: impl Into<Span>,
) -> serde_hjson::Result<Spanned<Value>> { ) -> serde_hjson::Result<Tagged<Value>> {
let v: serde_hjson::Value = serde_hjson::from_str(&s)?; 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, span))
} }
@ -48,20 +48,25 @@ pub fn from_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
let span = args.call_info.name_span; let span = args.call_info.name_span;
Ok(out Ok(out
.values .values
.map(move |a| match a.item { .map(move |a| {
Value::Primitive(Primitive::String(s)) => match from_json_string_to_value(s, span) { let value_span = a.span();
Ok(x) => ReturnSuccess::value(x.spanned(a.span)), match a.item {
Err(_) => Err(ShellError::maybe_labeled_error( Value::Primitive(Primitive::String(s)) => {
"Could not parse as JSON", match from_json_string_to_value(s, value_span) {
"piped data failed JSON parse", Ok(x) => ReturnSuccess::value(x),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as JSON",
"piped data failed JSON parse",
span,
)),
}
}
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span, span,
)), )),
}, }
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
}) })
.to_output_stream()) .to_output_stream())
} }

View file

@ -1,34 +1,32 @@
use crate::object::base::OF64; use crate::object::base::OF64;
use crate::object::{Primitive, SpannedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into<Span>) -> Spanned<Value> { fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into<Span>) -> Tagged<Value> {
let span = span.into(); let span = span.into();
match v { match v {
toml::Value::Boolean(b) => Value::Primitive(Primitive::Boolean(*b)).spanned(span), toml::Value::Boolean(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(span),
toml::Value::Integer(n) => Value::Primitive(Primitive::Int(*n)).spanned(span), toml::Value::Integer(n) => Value::Primitive(Primitive::Int(*n)).tagged(span),
toml::Value::Float(n) => Value::Primitive(Primitive::Float(OF64::from(*n))).spanned(span), toml::Value::Float(n) => Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(span),
toml::Value::String(s) => { toml::Value::String(s) => Value::Primitive(Primitive::String(String::from(s))).tagged(span),
Value::Primitive(Primitive::String(String::from(s))).spanned(span)
}
toml::Value::Array(a) => Value::List( toml::Value::Array(a) => Value::List(
a.iter() a.iter()
.map(|x| convert_toml_value_to_nu_value(x, span)) .map(|x| convert_toml_value_to_nu_value(x, span))
.collect(), .collect(),
) )
.spanned(span), .tagged(span),
toml::Value::Datetime(dt) => { toml::Value::Datetime(dt) => {
Value::Primitive(Primitive::String(dt.to_string())).spanned(span) Value::Primitive(Primitive::String(dt.to_string())).tagged(span)
} }
toml::Value::Table(t) => { toml::Value::Table(t) => {
let mut collected = SpannedDictBuilder::new(span); let mut collected = TaggedDictBuilder::new(span);
for (k, v) in t.iter() { for (k, v) in t.iter() {
collected.insert_spanned(k.clone(), convert_toml_value_to_nu_value(v, span)); collected.insert_tagged(k.clone(), convert_toml_value_to_nu_value(v, span));
} }
collected.into_spanned_value() collected.into_tagged_value()
} }
} }
} }
@ -36,7 +34,7 @@ fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into<Span>) -> Spa
pub fn from_toml_string_to_value( pub fn from_toml_string_to_value(
s: String, s: String,
span: impl Into<Span>, span: impl Into<Span>,
) -> Result<Spanned<Value>, Box<dyn std::error::Error>> { ) -> Result<Tagged<Value>, Box<dyn std::error::Error>> {
let v: toml::Value = s.parse::<toml::Value>()?; let v: toml::Value = s.parse::<toml::Value>()?;
Ok(convert_toml_value_to_nu_value(&v, span)) Ok(convert_toml_value_to_nu_value(&v, span))
} }
@ -46,20 +44,25 @@ pub fn from_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
let span = args.call_info.name_span; let span = args.call_info.name_span;
Ok(out Ok(out
.values .values
.map(move |a| match a.item { .map(move |a| {
Value::Primitive(Primitive::String(s)) => match from_toml_string_to_value(s, span) { let value_span = a.span();
Ok(x) => ReturnSuccess::value(x.spanned(a.span)), match a.item {
Err(_) => Err(ShellError::maybe_labeled_error( Value::Primitive(Primitive::String(s)) => {
"Could not parse as TOML", match from_toml_string_to_value(s, value_span) {
"piped data failed TOML parse", Ok(x) => ReturnSuccess::value(x),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as TOML",
"piped data failed TOML parse",
span,
)),
}
}
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span, span,
)), )),
}, }
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
}) })
.to_output_stream()) .to_output_stream())
} }

View file

@ -1,10 +1,7 @@
use crate::object::{Primitive, SpannedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
fn from_node_to_value<'a, 'd>( fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, span: impl Into<Span>) -> Tagged<Value> {
n: &roxmltree::Node<'a, 'd>,
span: impl Into<Span>,
) -> Spanned<Value> {
let span = span.into(); let span = span.into();
if n.is_element() { if n.is_element() {
@ -15,10 +12,10 @@ fn from_node_to_value<'a, 'd>(
children_values.push(from_node_to_value(&c, span)); children_values.push(from_node_to_value(&c, span));
} }
let children_values: Vec<Spanned<Value>> = children_values let children_values: Vec<Tagged<Value>> = children_values
.into_iter() .into_iter()
.filter(|x| match x { .filter(|x| match x {
Spanned { Tagged {
item: Value::Primitive(Primitive::String(f)), item: Value::Primitive(Primitive::String(f)),
.. ..
} => { } => {
@ -32,29 +29,29 @@ fn from_node_to_value<'a, 'd>(
}) })
.collect(); .collect();
let mut collected = SpannedDictBuilder::new(span); let mut collected = TaggedDictBuilder::new(span);
collected.insert(name.clone(), Value::List(children_values)); collected.insert(name.clone(), Value::List(children_values));
collected.into_spanned_value() collected.into_tagged_value()
} else if n.is_comment() { } else if n.is_comment() {
Value::string("<comment>").spanned(span) Value::string("<comment>").tagged(span)
} else if n.is_pi() { } else if n.is_pi() {
Value::string("<processing_instruction>").spanned(span) Value::string("<processing_instruction>").tagged(span)
} else if n.is_text() { } else if n.is_text() {
Value::string(n.text().unwrap()).spanned(span) Value::string(n.text().unwrap()).tagged(span)
} else { } else {
Value::string("<unknown>").spanned(span) Value::string("<unknown>").tagged(span)
} }
} }
fn from_document_to_value(d: &roxmltree::Document, span: impl Into<Span>) -> Spanned<Value> { fn from_document_to_value(d: &roxmltree::Document, span: impl Into<Span>) -> Tagged<Value> {
from_node_to_value(&d.root_element(), span) from_node_to_value(&d.root_element(), span)
} }
pub fn from_xml_string_to_value( pub fn from_xml_string_to_value(
s: String, s: String,
span: impl Into<Span>, span: impl Into<Span>,
) -> Result<Spanned<Value>, Box<dyn std::error::Error>> { ) -> Result<Tagged<Value>, Box<dyn std::error::Error>> {
let parsed = roxmltree::Document::parse(&s)?; let parsed = roxmltree::Document::parse(&s)?;
Ok(from_document_to_value(&parsed, span)) Ok(from_document_to_value(&parsed, span))
} }
@ -66,7 +63,7 @@ pub fn from_xml(args: CommandArgs) -> Result<OutputStream, ShellError> {
.values .values
.map(move |a| match a.item { .map(move |a| match a.item {
Value::Primitive(Primitive::String(s)) => match from_xml_string_to_value(s, span) { Value::Primitive(Primitive::String(s)) => match from_xml_string_to_value(s, span) {
Ok(x) => ReturnSuccess::value(x.spanned(a.span)), Ok(x) => ReturnSuccess::value(x),
Err(_) => Err(ShellError::maybe_labeled_error( Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as XML", "Could not parse as XML",
"piped data failed XML parse", "piped data failed XML parse",

View file

@ -1,41 +1,40 @@
use crate::object::base::OF64; use crate::object::base::OF64;
use crate::object::{Primitive, SpannedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, span: impl Into<Span>) -> Spanned<Value> { fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, span: impl Into<Span>) -> Tagged<Value> {
let span = span.into(); let span = span.into();
match v { match v {
serde_yaml::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).spanned(span), serde_yaml::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(span),
serde_yaml::Value::Number(n) if n.is_i64() => { serde_yaml::Value::Number(n) if n.is_i64() => {
Value::Primitive(Primitive::Int(n.as_i64().unwrap())).spanned(span) Value::Primitive(Primitive::Int(n.as_i64().unwrap())).tagged(span)
} }
serde_yaml::Value::Number(n) if n.is_f64() => { serde_yaml::Value::Number(n) if n.is_f64() => {
Value::Primitive(Primitive::Float(OF64::from(n.as_f64().unwrap()))).spanned(span) Value::Primitive(Primitive::Float(OF64::from(n.as_f64().unwrap()))).tagged(span)
} }
serde_yaml::Value::String(s) => Value::string(s).spanned(span), serde_yaml::Value::String(s) => Value::string(s).tagged(span),
serde_yaml::Value::Sequence(a) => Value::List( serde_yaml::Value::Sequence(a) => Value::List(
a.iter() a.iter()
.map(|x| convert_yaml_value_to_nu_value(x, span)) .map(|x| convert_yaml_value_to_nu_value(x, span))
.collect(), .collect(),
) )
.spanned(span), .tagged(span),
serde_yaml::Value::Mapping(t) => { serde_yaml::Value::Mapping(t) => {
let mut collected = SpannedDictBuilder::new(span); let mut collected = TaggedDictBuilder::new(span);
for (k, v) in t.iter() { for (k, v) in t.iter() {
match k { match k {
serde_yaml::Value::String(k) => { serde_yaml::Value::String(k) => {
collected collected.insert_tagged(k.clone(), convert_yaml_value_to_nu_value(v, span));
.insert_spanned(k.clone(), convert_yaml_value_to_nu_value(v, span));
} }
_ => unimplemented!("Unknown key type"), _ => unimplemented!("Unknown key type"),
} }
} }
collected.into_spanned_value() collected.into_tagged_value()
} }
serde_yaml::Value::Null => Value::Primitive(Primitive::Nothing).spanned(span), serde_yaml::Value::Null => Value::Primitive(Primitive::Nothing).tagged(span),
x => unimplemented!("Unsupported yaml case: {:?}", x), x => unimplemented!("Unsupported yaml case: {:?}", x),
} }
} }
@ -43,7 +42,7 @@ fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, span: impl Into<Span>)
pub fn from_yaml_string_to_value( pub fn from_yaml_string_to_value(
s: String, s: String,
span: impl Into<Span>, span: impl Into<Span>,
) -> serde_yaml::Result<Spanned<Value>> { ) -> serde_yaml::Result<Tagged<Value>> {
let v: serde_yaml::Value = serde_yaml::from_str(&s)?; 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, span))
} }
@ -53,20 +52,25 @@ pub fn from_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
let span = args.call_info.name_span; let span = args.call_info.name_span;
Ok(out Ok(out
.values .values
.map(move |a| match a.item { .map(move |a| {
Value::Primitive(Primitive::String(s)) => match from_yaml_string_to_value(s, span) { let value_span = a.span();
Ok(x) => ReturnSuccess::value(x.spanned(a.span)), match a.item {
Err(_) => Err(ShellError::maybe_labeled_error( Value::Primitive(Primitive::String(s)) => {
"Could not parse as YAML", match from_yaml_string_to_value(s, value_span) {
"piped data failed YAML parse", Ok(x) => ReturnSuccess::value(x),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as YAML",
"piped data failed YAML parse",
span,
)),
}
}
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span, span,
)), )),
}, }
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
}) })
.to_output_stream()) .to_output_stream())
} }

View file

@ -1,9 +1,8 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::Value; use crate::object::Value;
use crate::parser::Span;
use crate::prelude::*; use crate::prelude::*;
fn get_member(path: &str, span: Span, obj: &Spanned<Value>) -> Result<Spanned<Value>, ShellError> { fn get_member(path: &str, span: Span, obj: &Tagged<Value>) -> Result<Tagged<Value>, ShellError> {
let mut current = obj; let mut current = obj;
for p in path.split(".") { for p in path.split(".") {
match current.get_data_by_key(p) { match current.get_data_by_key(p) {
@ -44,7 +43,7 @@ pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
let fields: Result<Vec<(String, Span)>, _> = args let fields: Result<Vec<(String, Span)>, _> = args
.positional_iter() .positional_iter()
.map(|a| (a.as_string().map(|x| (x, a.span)))) .map(|a| (a.as_string().map(|x| (x, a.span()))))
.collect(); .collect();
let fields = fields?; let fields = fields?;
@ -56,7 +55,7 @@ pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
let mut result = VecDeque::new(); let mut result = VecDeque::new();
for field in &fields { for field in &fields {
match get_member(&field.0, field.1, &item) { match get_member(&field.0, field.1, &item) {
Ok(Spanned { Ok(Tagged {
item: Value::List(l), item: Value::List(l),
.. ..
}) => { }) => {

View file

@ -20,7 +20,7 @@ pub fn lines(args: CommandArgs) -> Result<OutputStream, ShellError> {
let mut result = VecDeque::new(); let mut result = VecDeque::new();
for s in split_result { for s in split_result {
result.push_back(ReturnSuccess::value( result.push_back(ReturnSuccess::value(
Value::Primitive(Primitive::String(s.into())).spanned_unknown(), Value::Primitive(Primitive::String(s.into())).tagged_unknown(),
)); ));
} }
result result

View file

@ -1,6 +1,5 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{dir_entry_dict, Primitive, Value}; use crate::object::{dir_entry_dict, Primitive, Value};
use crate::parser::Spanned;
use crate::prelude::*; use crate::prelude::*;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -9,7 +8,7 @@ pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
let path = env.path.to_path_buf(); let path = env.path.to_path_buf();
let mut full_path = PathBuf::from(path); let mut full_path = PathBuf::from(path);
match &args.nth(0) { match &args.nth(0) {
Some(Spanned { Some(Tagged {
item: Value::Primitive(Primitive::String(s)), item: Value::Primitive(Primitive::String(s)),
.. ..
}) => full_path.push(Path::new(&s)), }) => full_path.push(Path::new(&s)),
@ -24,7 +23,7 @@ pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
e.to_string(), e.to_string(),
e.to_string(), e.to_string(),
s.span, s.span(),
)); ));
} else { } else {
return Err(ShellError::maybe_labeled_error( return Err(ShellError::maybe_labeled_error(

View file

@ -1,7 +1,6 @@
use crate::context::SpanSource; use crate::context::SpanSource;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{Primitive, Switch, Value}; use crate::object::{Primitive, Switch, Value};
use crate::parser::parse::span::Span;
use crate::prelude::*; use crate::prelude::*;
use mime::Mime; use mime::Mime;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -9,7 +8,7 @@ use std::str::FromStr;
use uuid::Uuid; use uuid::Uuid;
command! { command! {
Open as open(args, path: Spanned<PathBuf>, --raw: Switch,) { Open as open(args, path: Tagged<PathBuf>, --raw: Switch,) {
let span = args.call_info.name_span; let span = args.call_info.name_span;
let cwd = args let cwd = args
@ -21,9 +20,9 @@ command! {
let full_path = PathBuf::from(cwd); let full_path = PathBuf::from(cwd);
let path_str = path.to_str().ok_or(ShellError::type_error("Path", "invalid path".spanned(path.span)))?; let path_str = path.to_str().ok_or(ShellError::type_error("Path", "invalid path".tagged(path.span())))?;
let (file_extension, contents, contents_span, span_source) = fetch(&full_path, path_str, path.span)?; let (file_extension, contents, contents_span, span_source) = fetch(&full_path, path_str, path.span())?;
let file_extension = if raw.is_present() { let file_extension = if raw.is_present() {
None None
@ -48,7 +47,7 @@ command! {
)?; )?;
match value { match value {
Spanned { item: Value::List(list), .. } => { Tagged { item: Value::List(list), .. } => {
for elem in list { for elem in list {
stream.push_back(ReturnSuccess::value(elem)); stream.push_back(ReturnSuccess::value(elem));
} }
@ -57,7 +56,7 @@ command! {
} }
}, },
other => stream.push_back(ReturnSuccess::value(other.spanned(contents_span))), other => stream.push_back(ReturnSuccess::value(other.tagged(contents_span))),
}; };
stream stream
@ -206,11 +205,11 @@ pub fn parse_as_value(
contents: String, contents: String,
contents_span: Span, contents_span: Span,
name_span: Option<Span>, name_span: Option<Span>,
) -> Result<Spanned<Value>, ShellError> { ) -> Result<Tagged<Value>, ShellError> {
match extension { match extension {
Some(x) if x == "csv" => { Some(x) if x == "csv" => {
crate::commands::from_csv::from_csv_string_to_value(contents, contents_span) crate::commands::from_csv::from_csv_string_to_value(contents, contents_span)
.map(|c| c.spanned(contents_span)) .map(|c| c.tagged(contents_span))
.map_err(move |_| { .map_err(move |_| {
ShellError::maybe_labeled_error( ShellError::maybe_labeled_error(
"Could not open as CSV", "Could not open as CSV",
@ -221,7 +220,7 @@ pub fn parse_as_value(
} }
Some(x) if x == "toml" => { Some(x) if x == "toml" => {
crate::commands::from_toml::from_toml_string_to_value(contents, contents_span) crate::commands::from_toml::from_toml_string_to_value(contents, contents_span)
.map(|c| c.spanned(contents_span)) .map(|c| c.tagged(contents_span))
.map_err(move |_| { .map_err(move |_| {
ShellError::maybe_labeled_error( ShellError::maybe_labeled_error(
"Could not open as TOML", "Could not open as TOML",
@ -232,7 +231,7 @@ pub fn parse_as_value(
} }
Some(x) if x == "json" => { Some(x) if x == "json" => {
crate::commands::from_json::from_json_string_to_value(contents, contents_span) crate::commands::from_json::from_json_string_to_value(contents, contents_span)
.map(|c| c.spanned(contents_span)) .map(|c| c.tagged(contents_span))
.map_err(move |_| { .map_err(move |_| {
ShellError::maybe_labeled_error( ShellError::maybe_labeled_error(
"Could not open as JSON", "Could not open as JSON",
@ -243,7 +242,7 @@ pub fn parse_as_value(
} }
Some(x) if x == "ini" => { Some(x) if x == "ini" => {
crate::commands::from_ini::from_ini_string_to_value(contents, contents_span) crate::commands::from_ini::from_ini_string_to_value(contents, contents_span)
.map(|c| c.spanned(contents_span)) .map(|c| c.tagged(contents_span))
.map_err(move |_| { .map_err(move |_| {
ShellError::maybe_labeled_error( ShellError::maybe_labeled_error(
"Could not open as INI", "Could not open as INI",
@ -285,6 +284,6 @@ pub fn parse_as_value(
}, },
) )
} }
_ => Ok(Value::string(contents).spanned(contents_span)), _ => Ok(Value::string(contents).tagged(contents_span)),
} }
} }

View file

@ -17,7 +17,7 @@ pub fn pick(args: CommandArgs) -> Result<OutputStream, ShellError> {
let objects = input let objects = input
.values .values
.map(move |value| select_fields(&value.item, &fields, value.span)); .map(move |value| select_fields(&value.item, &fields, value.span()));
Ok(objects.from_input_stream()) Ok(objects.from_input_stream())
} }

View file

@ -78,11 +78,11 @@ pub fn filter_plugin(path: String, args: CommandArgs) -> Result<OutputStream, Sh
.spawn() .spawn()
.expect("Failed to spawn child process"); .expect("Failed to spawn child process");
let mut bos: VecDeque<Spanned<Value>> = VecDeque::new(); let mut bos: VecDeque<Tagged<Value>> = VecDeque::new();
bos.push_back(Value::Primitive(Primitive::BeginningOfStream).spanned_unknown()); bos.push_back(Value::Primitive(Primitive::BeginningOfStream).tagged_unknown());
let mut eos: VecDeque<Spanned<Value>> = VecDeque::new(); let mut eos: VecDeque<Tagged<Value>> = VecDeque::new();
eos.push_back(Value::Primitive(Primitive::EndOfStream).spanned_unknown()); eos.push_back(Value::Primitive(Primitive::EndOfStream).tagged_unknown());
let call_info = args.call_info; let call_info = args.call_info;
@ -90,7 +90,7 @@ pub fn filter_plugin(path: String, args: CommandArgs) -> Result<OutputStream, Sh
.chain(args.input.values) .chain(args.input.values)
.chain(eos) .chain(eos)
.map(move |v| match v { .map(move |v| match v {
Spanned { Tagged {
item: Value::Primitive(Primitive::BeginningOfStream), item: Value::Primitive(Primitive::BeginningOfStream),
.. ..
} => { } => {
@ -136,7 +136,7 @@ pub fn filter_plugin(path: String, args: CommandArgs) -> Result<OutputStream, Sh
} }
} }
} }
Spanned { Tagged {
item: Value::Primitive(Primitive::EndOfStream), item: Value::Primitive(Primitive::EndOfStream),
.. ..
} => { } => {

View file

@ -17,9 +17,9 @@ pub fn reject(args: CommandArgs) -> Result<OutputStream, ShellError> {
let fields = fields?; let fields = fields?;
let stream = args.input.values.map(move |item| { let stream = args.input.values.map(move |item| {
reject_fields(&item, &fields, item.span) reject_fields(&item, &fields, item.span())
.into_spanned_value() .into_tagged_value()
.spanned(name_span) .tagged(name_span)
}); });
Ok(stream.from_input_stream()) Ok(stream.from_input_stream())

View file

@ -5,7 +5,7 @@ use crate::commands::to_toml::value_to_toml_value;
use crate::commands::to_yaml::value_to_yaml_value; use crate::commands::to_yaml::value_to_yaml_value;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{Primitive, Value}; use crate::object::{Primitive, Value};
use crate::parser::Spanned; use crate::Tagged;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> { pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
@ -30,7 +30,7 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
} }
let save_raw = match positional.get(1) { let save_raw = match positional.get(1) {
Some(Spanned { Some(Tagged {
item: Value::Primitive(Primitive::String(s)), item: Value::Primitive(Primitive::String(s)),
.. ..
}) if s == "--raw" => true, }) if s == "--raw" => true,

View file

@ -1,5 +1,5 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{SpannedDictBuilder, Value}; use crate::object::{TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
pub fn size(args: CommandArgs) -> Result<OutputStream, ShellError> { pub fn size(args: CommandArgs) -> Result<OutputStream, ShellError> {
@ -7,17 +7,17 @@ pub fn size(args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(input Ok(input
.values .values
.map(move |v| match v.item { .map(move |v| match v.item {
Value::Primitive(Primitive::String(s)) => ReturnSuccess::value(count(&s, v.span)), Value::Primitive(Primitive::String(ref s)) => ReturnSuccess::value(count(s, v.span())),
_ => Err(ShellError::maybe_labeled_error( _ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline", "Expected string values from pipeline",
"expects strings from pipeline", "expects strings from pipeline",
Some(v.span), Some(v.span()),
)), )),
}) })
.to_output_stream()) .to_output_stream())
} }
fn count(contents: &str, span: impl Into<Span>) -> Spanned<Value> { fn count(contents: &str, span: impl Into<Span>) -> Tagged<Value> {
let mut lines: i64 = 0; let mut lines: i64 = 0;
let mut words: i64 = 0; let mut words: i64 = 0;
let mut chars: i64 = 0; let mut chars: i64 = 0;
@ -42,7 +42,7 @@ fn count(contents: &str, span: impl Into<Span>) -> Spanned<Value> {
} }
} }
let mut dict = SpannedDictBuilder::new(span); let mut dict = TaggedDictBuilder::new(span);
//TODO: add back in name when we have it in the span //TODO: add back in name when we have it in the span
//dict.insert("name", Value::string(name)); //dict.insert("name", Value::string(name));
dict.insert("lines", Value::int(lines)); dict.insert("lines", Value::int(lines));
@ -50,5 +50,5 @@ fn count(contents: &str, span: impl Into<Span>) -> Spanned<Value> {
dict.insert("chars", Value::int(chars)); dict.insert("chars", Value::int(chars));
dict.insert("max length", Value::int(bytes)); dict.insert("max length", Value::int(bytes));
dict.into_spanned_value() dict.into_tagged_value()
} }

View file

@ -12,7 +12,7 @@ pub fn sort_by(args: CommandArgs) -> Result<OutputStream, ShellError> {
fields fields
.iter() .iter()
.map(|f| item.get_data_by_key(f).map(|i| i.clone())) .map(|f| item.get_data_by_key(f).map(|i| i.clone()))
.collect::<Vec<Option<Spanned<Value>>>>() .collect::<Vec<Option<Tagged<Value>>>>()
}); });
vec.into_iter().collect::<VecDeque<_>>() vec.into_iter().collect::<VecDeque<_>>()

View file

@ -1,5 +1,5 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{Primitive, SpannedDictBuilder, Value}; use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
use log::trace; use log::trace;
@ -20,7 +20,7 @@ pub fn split_column(args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(input Ok(input
.values .values
.map(move |v| match v.item { .map(move |v| match v.item {
Value::Primitive(Primitive::String(s)) => { Value::Primitive(Primitive::String(ref s)) => {
let splitter = positional[0].as_string().unwrap().replace("\\n", "\n"); let splitter = positional[0].as_string().unwrap().replace("\\n", "\n");
trace!("splitting with {:?}", splitter); trace!("splitting with {:?}", splitter);
let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect(); let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect();
@ -34,27 +34,27 @@ pub fn split_column(args: CommandArgs) -> Result<OutputStream, ShellError> {
gen_columns.push(format!("Column{}", i + 1)); gen_columns.push(format!("Column{}", i + 1));
} }
let mut dict = SpannedDictBuilder::new(v.span); let mut dict = TaggedDictBuilder::new(v.span());
for (&k, v) in split_result.iter().zip(gen_columns.iter()) { for (&k, v) in split_result.iter().zip(gen_columns.iter()) {
dict.insert(v.clone(), Primitive::String(k.into())); dict.insert(v.clone(), Primitive::String(k.into()));
} }
ReturnSuccess::value(dict.into_spanned_value()) ReturnSuccess::value(dict.into_tagged_value())
} else if split_result.len() == (positional.len() - 1) { } else if split_result.len() == (positional.len() - 1) {
let mut dict = SpannedDictBuilder::new(v.span); let mut dict = TaggedDictBuilder::new(v.span());
for (&k, v) in split_result.iter().zip(positional.iter().skip(1)) { for (&k, v) in split_result.iter().zip(positional.iter().skip(1)) {
dict.insert( dict.insert(
v.as_string().unwrap(), v.as_string().unwrap(),
Value::Primitive(Primitive::String(k.into())), Value::Primitive(Primitive::String(k.into())),
); );
} }
ReturnSuccess::value(dict.into_spanned_value()) ReturnSuccess::value(dict.into_tagged_value())
} else { } else {
let mut dict = SpannedDictBuilder::new(v.span); let mut dict = TaggedDictBuilder::new(v.span());
for k in positional.iter().skip(1) { for k in positional.iter().skip(1) {
dict.insert(k.as_string().unwrap().trim(), Primitive::String("".into())); dict.insert(k.as_string().unwrap().trim(), Primitive::String("".into()));
} }
ReturnSuccess::value(dict.into_spanned_value()) ReturnSuccess::value(dict.into_tagged_value())
} }
} }
_ => Err(ShellError::maybe_labeled_error( _ => Err(ShellError::maybe_labeled_error(

View file

@ -1,11 +1,10 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{Primitive, Value}; use crate::object::{Primitive, Value};
use crate::parser::Spanned;
use crate::prelude::*; use crate::prelude::*;
use log::trace; use log::trace;
pub fn split_row(args: CommandArgs) -> Result<OutputStream, ShellError> { pub fn split_row(args: CommandArgs) -> Result<OutputStream, ShellError> {
let positional: Vec<Spanned<Value>> = args.positional_iter().cloned().collect(); let positional: Vec<Tagged<Value>> = args.positional_iter().cloned().collect();
let span = args.call_info.name_span; let span = args.call_info.name_span;
if positional.len() == 0 { if positional.len() == 0 {
@ -21,7 +20,7 @@ pub fn split_row(args: CommandArgs) -> Result<OutputStream, ShellError> {
let stream = input let stream = input
.values .values
.map(move |v| match v.item { .map(move |v| match v.item {
Value::Primitive(Primitive::String(s)) => { Value::Primitive(Primitive::String(ref s)) => {
let splitter = positional[0].as_string().unwrap().replace("\\n", "\n"); let splitter = positional[0].as_string().unwrap().replace("\\n", "\n");
trace!("splitting with {:?}", splitter); trace!("splitting with {:?}", splitter);
let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect(); let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect();
@ -31,7 +30,7 @@ pub fn split_row(args: CommandArgs) -> Result<OutputStream, ShellError> {
let mut result = VecDeque::new(); let mut result = VecDeque::new();
for s in split_result { for s in split_result {
result.push_back(ReturnSuccess::value( result.push_back(ReturnSuccess::value(
Value::Primitive(Primitive::String(s.into())).spanned(v.span), Value::Primitive(Primitive::String(s.into())).tagged(v.span()),
)); ));
} }
result result

32
src/commands/tags.rs Normal file
View file

@ -0,0 +1,32 @@
use crate::errors::ShellError;
use crate::object::{TaggedDictBuilder, Value};
use crate::prelude::*;
pub fn tags(args: CommandArgs) -> Result<OutputStream, ShellError> {
let source_map = args.call_info.source_map.clone();
Ok(args
.input
.values
.map(move |v| {
let mut tags = TaggedDictBuilder::new(v.span());
{
let span = v.span();
let mut dict = TaggedDictBuilder::new(v.span());
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() {
Some(SpanSource::File(source)) => {
dict.insert("source", Value::string(source));
}
Some(SpanSource::Url(source)) => {
dict.insert("source", Value::string(source));
}
_ => {}
}
tags.insert_tagged("span", dict.into_tagged_value());
}
tags.into_tagged_value()
})
.to_output_stream())
}

View file

@ -5,7 +5,7 @@ pub fn to_array(args: CommandArgs) -> Result<OutputStream, ShellError> {
let out = args.input.values.collect(); let out = args.input.values.collect();
Ok(out Ok(out
.map(|vec: Vec<_>| stream![Value::List(vec).spanned_unknown()]) // TODO: args.input should have a span .map(|vec: Vec<_>| stream![Value::List(vec).tagged_unknown()]) // TODO: args.input should have a span
.flatten_stream() .flatten_stream()
.from_input_stream()) .from_input_stream())
} }

View file

@ -9,7 +9,7 @@ pub fn value_to_csv_value(v: &Value) -> Value {
Value::Object(o) => Value::Object(o.clone()), Value::Object(o) => Value::Object(o.clone()),
Value::List(l) => Value::List(l.clone()), Value::List(l) => Value::List(l.clone()),
Value::Block(_) => Value::Primitive(Primitive::Nothing), Value::Block(_) => Value::Primitive(Primitive::Nothing),
_ => Value::Primitive(Primitive::Nothing) _ => Value::Primitive(Primitive::Nothing),
} }
} }
@ -29,10 +29,10 @@ pub fn to_string(v: &Value) -> Result<String, Box<dyn std::error::Error>> {
wtr.write_record(fields).expect("can not write."); wtr.write_record(fields).expect("can not write.");
wtr.write_record(values).expect("can not write."); wtr.write_record(values).expect("can not write.");
return Ok(String::from_utf8(wtr.into_inner()?)?) return Ok(String::from_utf8(wtr.into_inner()?)?);
}, }
Value::Primitive(Primitive::String(s)) => return Ok(s.to_string()), Value::Primitive(Primitive::String(s)) => return Ok(s.to_string()),
_ => return Err("Bad input".into()) _ => return Err("Bad input".into()),
} }
} }
@ -41,18 +41,13 @@ pub fn to_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name_span = args.call_info.name_span; let name_span = args.call_info.name_span;
Ok(out Ok(out
.values .values
.map( .map(move |a| match to_string(&value_to_csv_value(&a.item)) {
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) => { "Can not convert to CSV string",
ReturnSuccess::value(Value::Primitive(Primitive::String(x)).spanned(name_span)) "can not convert piped data to CSV string",
} name_span,
Err(_) => Err(ShellError::maybe_labeled_error( )),
"Can not convert to CSV string", })
"can not convert piped data to CSV string",
name_span,
)),
},
)
.to_output_stream()) .to_output_stream())
} }

View file

@ -49,7 +49,7 @@ pub fn to_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
.map( .map(
move |a| match serde_json::to_string(&value_to_json_value(&a)) { move |a| match serde_json::to_string(&value_to_json_value(&a)) {
Ok(x) => { Ok(x) => {
ReturnSuccess::value(Value::Primitive(Primitive::String(x)).spanned(name_span)) ReturnSuccess::value(Value::Primitive(Primitive::String(x)).tagged(name_span))
} }
Err(_) => Err(ShellError::maybe_labeled_error( Err(_) => Err(ShellError::maybe_labeled_error(
"Can not convert to JSON string", "Can not convert to JSON string",

View file

@ -42,13 +42,13 @@ pub fn to_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
.map(move |a| match toml::to_string(&value_to_toml_value(&a)) { .map(move |a| match toml::to_string(&value_to_toml_value(&a)) {
Ok(val) => { Ok(val) => {
return ReturnSuccess::value( return ReturnSuccess::value(
Value::Primitive(Primitive::String(val)).spanned(name_span), Value::Primitive(Primitive::String(val)).tagged(name_span),
) )
} }
Err(err) => Err(ShellError::type_error( Err(err) => Err(ShellError::type_error(
"Can not convert to a TOML string", "Can not convert to a TOML string",
format!("{:?} - {:?}", a.type_name(), err).spanned(name_span), format!("{:?} - {:?}", a.type_name(), err).tagged(name_span),
)), )),
}) })
.to_output_stream()) .to_output_stream())

View file

@ -47,7 +47,7 @@ pub fn to_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
.map( .map(
move |a| match serde_yaml::to_string(&value_to_yaml_value(&a)) { move |a| match serde_yaml::to_string(&value_to_yaml_value(&a)) {
Ok(x) => { Ok(x) => {
ReturnSuccess::value(Value::Primitive(Primitive::String(x)).spanned(name_span)) ReturnSuccess::value(Value::Primitive(Primitive::String(x)).tagged(name_span))
} }
Err(_) => Err(ShellError::maybe_labeled_error( Err(_) => Err(ShellError::maybe_labeled_error(
"Can not convert to YAML string", "Can not convert to YAML string",

View file

@ -9,7 +9,7 @@ pub fn trim(args: CommandArgs) -> Result<OutputStream, ShellError> {
.values .values
.map(move |v| { .map(move |v| {
let string = String::extract(&v)?; let string = String::extract(&v)?;
ReturnSuccess::value(Value::string(string.trim()).spanned(v.span)) ReturnSuccess::value(Value::string(string.trim()).tagged(v.span()))
}) })
.to_output_stream()) .to_output_stream())
} }

View file

@ -1,8 +1,5 @@
use crate::commands::command::{CallInfo, Sink, SinkCommandArgs}; use crate::commands::command::{CallInfo, Sink, SinkCommandArgs};
use crate::parser::{ use crate::parser::registry::{Args, CommandConfig, CommandRegistry};
registry::{Args, CommandConfig, CommandRegistry},
Span,
};
use crate::prelude::*; use crate::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid; use uuid::Uuid;
@ -84,7 +81,7 @@ impl Context {
command: Arc<dyn Sink>, command: Arc<dyn Sink>,
name_span: Option<Span>, name_span: Option<Span>,
args: Args, args: Args,
input: Vec<Spanned<Value>>, input: Vec<Tagged<Value>>,
) -> Result<(), ShellError> { ) -> Result<(), ShellError> {
let command_args = SinkCommandArgs { let command_args = SinkCommandArgs {
ctx: self.clone(), ctx: self.clone(),

View file

@ -1,7 +1,6 @@
#[allow(unused)] #[allow(unused)]
use crate::prelude::*; use crate::prelude::*;
use crate::parser::{Span, Spanned};
use ansi_term::Color; use ansi_term::Color;
use derive_new::new; use derive_new::new;
use language_reporting::{Diagnostic, Label, Severity}; use language_reporting::{Diagnostic, Label, Severity};
@ -9,23 +8,21 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Serialize, Deserialize)] #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Serialize, Deserialize)]
pub enum Description { pub enum Description {
Source(Spanned<String>), Source(Tagged<String>),
Synthetic(String), Synthetic(String),
} }
impl Description { impl Description {
pub fn from(item: Spanned<impl Into<String>>) -> Description { pub fn from(value: Tagged<impl Into<String>>) -> Description {
match item { let value_span = value.span();
Spanned {
span: match value_span {
Span { Span {
start: 0, start: 0,
end: 0, end: 0,
source: None, source: None,
}, } => Description::Synthetic(value.item.into()),
item, _ => Description::Source(Tagged::from_item(value.item.into(), value_span)),
} => Description::Synthetic(item.into()),
Spanned { span, item } => Description::Source(Spanned::from_item(item.into(), span)),
} }
} }
} }
@ -33,7 +30,7 @@ impl Description {
impl Description { impl Description {
fn into_label(self) -> Result<Label<Span>, String> { fn into_label(self) -> Result<Label<Span>, String> {
match self { match self {
Description::Source(s) => Ok(Label::new_primary(s.span).with_message(s.item)), Description::Source(s) => Ok(Label::new_primary(s.span()).with_message(s.item)),
Description::Synthetic(s) => Err(s), Description::Synthetic(s) => Err(s),
} }
} }
@ -65,7 +62,7 @@ pub struct ShellError {
impl ShellError { impl ShellError {
crate fn type_error( crate fn type_error(
expected: impl Into<String>, expected: impl Into<String>,
actual: Spanned<impl Into<String>>, actual: Tagged<impl Into<String>>,
) -> ShellError { ) -> ShellError {
ProximateShellError::TypeError { ProximateShellError::TypeError {
expected: expected.into(), expected: expected.into(),
@ -75,8 +72,8 @@ impl ShellError {
} }
crate fn coerce_error( crate fn coerce_error(
left: Spanned<impl Into<String>>, left: Tagged<impl Into<String>>,
right: Spanned<impl Into<String>>, right: Tagged<impl Into<String>>,
) -> ShellError { ) -> ShellError {
ProximateShellError::CoerceError { ProximateShellError::CoerceError {
left: left.map(|l| l.into()), left: left.map(|l| l.into()),
@ -166,9 +163,9 @@ impl ShellError {
ProximateShellError::TypeError { ProximateShellError::TypeError {
expected, expected,
actual: actual:
Spanned { Tagged {
item: Some(actual), item: Some(actual),
span, tag: Tag { span },
}, },
} => Diagnostic::new(Severity::Error, "Type Error").with_label( } => Diagnostic::new(Severity::Error, "Type Error").with_label(
Label::new_primary(span) Label::new_primary(span)
@ -177,7 +174,11 @@ impl ShellError {
ProximateShellError::TypeError { ProximateShellError::TypeError {
expected, expected,
actual: Spanned { item: None, span }, actual:
Tagged {
item: None,
tag: Tag { span },
},
} => Diagnostic::new(Severity::Error, "Type Error") } => Diagnostic::new(Severity::Error, "Type Error")
.with_label(Label::new_primary(span).with_message(expected)), .with_label(Label::new_primary(span).with_message(expected)),
@ -202,8 +203,8 @@ impl ShellError {
ProximateShellError::Diagnostic(diag) => diag.diagnostic, ProximateShellError::Diagnostic(diag) => diag.diagnostic,
ProximateShellError::CoerceError { left, right } => { ProximateShellError::CoerceError { left, right } => {
Diagnostic::new(Severity::Error, "Coercion error") Diagnostic::new(Severity::Error, "Coercion error")
.with_label(Label::new_primary(left.span).with_message(left.item)) .with_label(Label::new_primary(left.span()).with_message(left.item))
.with_label(Label::new_secondary(right.span).with_message(right.item)) .with_label(Label::new_secondary(right.span()).with_message(right.item))
} }
} }
} }
@ -251,7 +252,7 @@ pub enum ProximateShellError {
String(StringError), String(StringError),
TypeError { TypeError {
expected: String, expected: String,
actual: Spanned<Option<String>>, actual: Tagged<Option<String>>,
}, },
MissingProperty { MissingProperty {
subpath: Description, subpath: Description,
@ -264,8 +265,8 @@ pub enum ProximateShellError {
}, },
Diagnostic(ShellDiagnostic), Diagnostic(ShellDiagnostic),
CoerceError { CoerceError {
left: Spanned<String>, left: Tagged<String>,
right: Spanned<String>, right: Tagged<String>,
}, },
} }
impl ProximateShellError { impl ProximateShellError {

View file

@ -2,7 +2,7 @@ use crate::errors::Description;
use crate::object::base::Block; use crate::object::base::Block;
use crate::parser::{ use crate::parser::{
hir::{self, Expression, RawExpression}, hir::{self, Expression, RawExpression},
CommandRegistry, Spanned, Text, CommandRegistry, Text,
}; };
use crate::prelude::*; use crate::prelude::*;
use derive_new::new; use derive_new::new;
@ -10,15 +10,15 @@ use indexmap::IndexMap;
#[derive(new)] #[derive(new)]
crate struct Scope { crate struct Scope {
it: Spanned<Value>, it: Tagged<Value>,
#[new(default)] #[new(default)]
vars: IndexMap<String, Spanned<Value>>, vars: IndexMap<String, Tagged<Value>>,
} }
impl Scope { impl Scope {
crate fn empty() -> Scope { crate fn empty() -> Scope {
Scope { Scope {
it: Value::nothing().spanned_unknown(), it: Value::nothing().tagged_unknown(),
vars: IndexMap::new(), vars: IndexMap::new(),
} }
} }
@ -29,7 +29,7 @@ crate fn evaluate_baseline_expr(
registry: &dyn CommandRegistry, registry: &dyn CommandRegistry,
scope: &Scope, scope: &Scope,
source: &Text, source: &Text,
) -> Result<Spanned<Value>, ShellError> { ) -> Result<Tagged<Value>, ShellError> {
match &expr.item { match &expr.item {
RawExpression::Literal(literal) => Ok(evaluate_literal(expr.copy_span(*literal), source)), RawExpression::Literal(literal) => Ok(evaluate_literal(expr.copy_span(*literal), source)),
RawExpression::Variable(var) => evaluate_reference(var, scope, source), RawExpression::Variable(var) => evaluate_reference(var, scope, source),
@ -38,15 +38,15 @@ crate fn evaluate_baseline_expr(
let right = evaluate_baseline_expr(binary.right(), registry, scope, source)?; let right = evaluate_baseline_expr(binary.right(), registry, scope, source)?;
match left.compare(binary.op(), &*right) { match left.compare(binary.op(), &*right) {
Ok(result) => Ok(Spanned::from_item(Value::boolean(result), *expr.span())), Ok(result) => Ok(Tagged::from_item(Value::boolean(result), expr.span())),
Err((left_type, right_type)) => Err(ShellError::coerce_error( Err((left_type, right_type)) => Err(ShellError::coerce_error(
binary.left().copy_span(left_type), binary.left().copy_span(left_type),
binary.right().copy_span(right_type), binary.right().copy_span(right_type),
)), )),
} }
} }
RawExpression::Block(block) => Ok(Spanned::from_item( RawExpression::Block(block) => Ok(Tagged::from_item(
Value::Block(Block::new(block.clone(), source.clone(), *expr.span())), Value::Block(Block::new(block.clone(), source.clone(), expr.span())),
expr.span(), expr.span(),
)), )),
RawExpression::Path(path) => { RawExpression::Path(path) => {
@ -59,12 +59,12 @@ crate fn evaluate_baseline_expr(
match next { match next {
None => { None => {
return Err(ShellError::missing_property( return Err(ShellError::missing_property(
Description::from(item.spanned_type_name()), Description::from(item.tagged_type_name()),
Description::from(name.clone()), Description::from(name.clone()),
)) ))
} }
Some(next) => { Some(next) => {
item = Spanned::from_item( item = Tagged::from_item(
next.clone().item, next.clone().item,
(expr.span().start, name.span().end), (expr.span().start, name.span().end),
) )
@ -72,13 +72,13 @@ crate fn evaluate_baseline_expr(
}; };
} }
Ok(Spanned::from_item(item.item().clone(), expr.span())) Ok(Tagged::from_item(item.item().clone(), expr.span()))
} }
RawExpression::Boolean(_boolean) => unimplemented!(), RawExpression::Boolean(_boolean) => unimplemented!(),
} }
} }
fn evaluate_literal(literal: Spanned<hir::Literal>, source: &Text) -> Spanned<Value> { fn evaluate_literal(literal: Tagged<hir::Literal>, source: &Text) -> Tagged<Value> {
let result = match literal.item { let result = match literal.item {
hir::Literal::Integer(int) => Value::int(int), hir::Literal::Integer(int) => Value::int(int),
hir::Literal::Size(int, unit) => unit.compute(int), hir::Literal::Size(int, unit) => unit.compute(int),
@ -93,13 +93,13 @@ fn evaluate_reference(
name: &hir::Variable, name: &hir::Variable,
scope: &Scope, scope: &Scope,
source: &Text, source: &Text,
) -> Result<Spanned<Value>, ShellError> { ) -> Result<Tagged<Value>, ShellError> {
match name { match name {
hir::Variable::It(span) => Ok(Spanned::from_item(scope.it.item.clone(), span)), hir::Variable::It(span) => Ok(Tagged::from_item(scope.it.item.clone(), span)),
hir::Variable::Other(span) => Ok(scope hir::Variable::Other(span) => Ok(scope
.vars .vars
.get(span.slice(source)) .get(span.slice(source))
.map(|v| v.clone()) .map(|v| v.clone())
.unwrap_or_else(|| Value::nothing().spanned(span))), .unwrap_or_else(|| Value::nothing().tagged(span))),
} }
} }

View file

@ -14,7 +14,7 @@ pub struct TableView {
} }
impl TableView { impl TableView {
fn merge_descriptors(values: &[Spanned<Value>]) -> Vec<String> { fn merge_descriptors(values: &[Tagged<Value>]) -> Vec<String> {
let mut ret = vec![]; let mut ret = vec![];
for value in values { for value in values {
for desc in value.data_descriptors() { for desc in value.data_descriptors() {
@ -26,7 +26,7 @@ impl TableView {
ret ret
} }
pub fn from_list(values: &[Spanned<Value>]) -> Option<TableView> { pub fn from_list(values: &[Tagged<Value>]) -> Option<TableView> {
if values.len() == 0 { if values.len() == 0 {
return None; return None;
} }

View file

@ -12,7 +12,7 @@ pub struct VTableView {
} }
impl VTableView { impl VTableView {
pub fn from_list(values: &[Spanned<Value>]) -> Option<VTableView> { pub fn from_list(values: &[Tagged<Value>]) -> Option<VTableView> {
if values.len() == 0 { if values.len() == 0 {
return None; return None;
} }

View file

@ -28,13 +28,11 @@ pub use crate::commands::command::{CallInfo, ReturnSuccess, ReturnValue};
pub use crate::context::{SourceMap, SpanSource}; pub use crate::context::{SourceMap, SpanSource};
pub use crate::env::host::BasicHost; pub use crate::env::host::BasicHost;
pub use crate::object::base::OF64; pub use crate::object::base::OF64;
pub use crate::parser::parse::span::Span;
pub use crate::parser::parse::span::SpannedItem;
pub use crate::parser::Spanned;
pub use crate::plugin::{serve_plugin, Plugin}; pub use crate::plugin::{serve_plugin, Plugin};
pub use cli::cli; pub use cli::cli;
pub use errors::ShellError; pub use errors::ShellError;
pub use object::base::{Primitive, Value}; pub use object::base::{Primitive, Value};
pub use object::dict::{Dictionary, SpannedDictBuilder}; pub use object::dict::{Dictionary, TaggedDictBuilder};
pub use object::meta::{Span, Tag, Tagged, TaggedItem};
pub use parser::parse::text::Text; pub use parser::parse::text::Text;
pub use parser::registry::{Args, CommandConfig, NamedType, PositionalType}; pub use parser::registry::{Args, CommandConfig, NamedType, PositionalType};

View file

@ -3,9 +3,10 @@ crate mod config;
crate mod dict; crate mod dict;
crate mod files; crate mod files;
crate mod into; crate mod into;
crate mod meta;
crate mod process; crate mod process;
crate mod types; crate mod types;
crate use base::{Block, Primitive, Switch, Value}; crate use base::{Block, Primitive, Switch, Value};
crate use dict::{Dictionary, SpannedDictBuilder}; crate use dict::{Dictionary, TaggedDictBuilder};
crate use files::dir_entry_dict; crate use files::dir_entry_dict;

View file

@ -1,7 +1,7 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::evaluate::{evaluate_baseline_expr, Scope}; use crate::evaluate::{evaluate_baseline_expr, Scope};
use crate::object::SpannedDictBuilder; use crate::object::TaggedDictBuilder;
use crate::parser::{hir, Operator, Span, Spanned}; use crate::parser::{hir, Operator};
use crate::prelude::*; use crate::prelude::*;
use crate::Text; use crate::Text;
use ansi_term::Color; use ansi_term::Color;
@ -164,11 +164,11 @@ impl Deserialize<'de> for Block {
} }
impl Block { impl Block {
pub fn invoke(&self, value: &Spanned<Value>) -> Result<Spanned<Value>, ShellError> { pub fn invoke(&self, value: &Tagged<Value>) -> Result<Tagged<Value>, ShellError> {
let scope = Scope::new(value.clone()); let scope = Scope::new(value.clone());
if self.expressions.len() == 0 { if self.expressions.len() == 0 {
return Ok(Spanned::from_item(Value::nothing(), self.span)); return Ok(Tagged::from_item(Value::nothing(), self.span));
} }
let mut last = None; let mut last = None;
@ -187,17 +187,17 @@ pub enum Value {
Object(crate::object::Dictionary), Object(crate::object::Dictionary),
#[serde(with = "serde_bytes")] #[serde(with = "serde_bytes")]
Binary(Vec<u8>), Binary(Vec<u8>),
List(Vec<Spanned<Value>>), List(Vec<Tagged<Value>>),
#[allow(unused)] #[allow(unused)]
Block(Block), Block(Block),
} }
pub fn debug_list(values: &'a Vec<Spanned<Value>>) -> ValuesDebug<'a> { pub fn debug_list(values: &'a Vec<Tagged<Value>>) -> ValuesDebug<'a> {
ValuesDebug { values } ValuesDebug { values }
} }
pub struct ValuesDebug<'a> { pub struct ValuesDebug<'a> {
values: &'a Vec<Spanned<Value>>, values: &'a Vec<Tagged<Value>>,
} }
impl fmt::Debug for ValuesDebug<'a> { impl fmt::Debug for ValuesDebug<'a> {
@ -209,7 +209,7 @@ impl fmt::Debug for ValuesDebug<'a> {
} }
pub struct ValueDebug<'a> { pub struct ValueDebug<'a> {
value: &'a Spanned<Value>, value: &'a Tagged<Value>,
} }
impl fmt::Debug for ValueDebug<'a> { impl fmt::Debug for ValueDebug<'a> {
@ -224,17 +224,17 @@ impl fmt::Debug for ValueDebug<'a> {
} }
} }
impl Spanned<Value> { impl Tagged<Value> {
crate fn spanned_type_name(&self) -> Spanned<String> { crate fn tagged_type_name(&self) -> Tagged<String> {
let name = self.type_name(); let name = self.type_name();
Spanned::from_item(name, self.span) Tagged::from_item(name, self.span())
} }
} }
impl std::convert::TryFrom<&'a Spanned<Value>> for Block { impl std::convert::TryFrom<&'a Tagged<Value>> for Block {
type Error = ShellError; type Error = ShellError;
fn try_from(value: &'a Spanned<Value>) -> Result<Block, ShellError> { fn try_from(value: &'a Tagged<Value>) -> Result<Block, ShellError> {
match value.item() { match value.item() {
Value::Block(block) => Ok(block.clone()), Value::Block(block) => Ok(block.clone()),
v => Err(ShellError::type_error( v => Err(ShellError::type_error(
@ -245,10 +245,10 @@ impl std::convert::TryFrom<&'a Spanned<Value>> for Block {
} }
} }
impl std::convert::TryFrom<&'a Spanned<Value>> for i64 { impl std::convert::TryFrom<&'a Tagged<Value>> for i64 {
type Error = ShellError; type Error = ShellError;
fn try_from(value: &'a Spanned<Value>) -> Result<i64, ShellError> { fn try_from(value: &'a Tagged<Value>) -> Result<i64, ShellError> {
match value.item() { match value.item() {
Value::Primitive(Primitive::Int(int)) => Ok(*int), Value::Primitive(Primitive::Int(int)) => Ok(*int),
v => Err(ShellError::type_error( v => Err(ShellError::type_error(
@ -273,10 +273,10 @@ impl Switch {
} }
} }
impl std::convert::TryFrom<Option<&'a Spanned<Value>>> for Switch { impl std::convert::TryFrom<Option<&'a Tagged<Value>>> for Switch {
type Error = ShellError; type Error = ShellError;
fn try_from(value: Option<&'a Spanned<Value>>) -> Result<Switch, ShellError> { fn try_from(value: Option<&'a Tagged<Value>>) -> Result<Switch, ShellError> {
match value { match value {
None => Ok(Switch::Absent), None => Ok(Switch::Absent),
Some(value) => match value.item() { Some(value) => match value.item() {
@ -290,7 +290,7 @@ impl std::convert::TryFrom<Option<&'a Spanned<Value>>> for Switch {
} }
} }
impl Spanned<Value> { impl Tagged<Value> {
crate fn debug(&'a self) -> ValueDebug<'a> { crate fn debug(&'a self) -> ValueDebug<'a> {
ValueDebug { value: self } ValueDebug { value: self }
} }
@ -322,13 +322,13 @@ impl Value {
} }
} }
crate fn get_data_by_key(&'a self, name: &str) -> Option<&Spanned<Value>> { crate fn get_data_by_key(&'a self, name: &str) -> Option<&Tagged<Value>> {
match self { match self {
Value::Object(o) => o.get_data_by_key(name), Value::Object(o) => o.get_data_by_key(name),
Value::List(l) => { Value::List(l) => {
for item in l { for item in l {
match item { match item {
Spanned { Tagged {
item: Value::Object(o), item: Value::Object(o),
.. ..
} => match o.get_data_by_key(name) { } => match o.get_data_by_key(name) {
@ -345,14 +345,14 @@ impl Value {
} }
#[allow(unused)] #[allow(unused)]
crate fn get_data_by_index(&'a self, idx: usize) -> Option<&Spanned<Value>> { crate fn get_data_by_index(&'a self, idx: usize) -> Option<&Tagged<Value>> {
match self { match self {
Value::List(l) => l.iter().nth(idx), Value::List(l) => l.iter().nth(idx),
_ => None, _ => None,
} }
} }
pub fn get_data_by_path(&'a self, span: Span, path: &str) -> Option<Spanned<&Value>> { pub fn get_data_by_path(&'a self, span: Span, path: &str) -> Option<Tagged<&Value>> {
let mut current = self; let mut current = self;
for p in path.split(".") { for p in path.split(".") {
match current.get_data_by_key(p) { match current.get_data_by_key(p) {
@ -361,10 +361,7 @@ impl Value {
} }
} }
Some(Spanned { Some(Tagged::from_item(current, span))
item: current,
span,
})
} }
pub fn insert_data_at_path( pub fn insert_data_at_path(
@ -372,7 +369,7 @@ impl Value {
span: Span, span: Span,
path: &str, path: &str,
new_value: Value, new_value: Value,
) -> Option<Spanned<Value>> { ) -> Option<Tagged<Value>> {
let mut new_obj = self.clone(); let mut new_obj = self.clone();
let split_path: Vec<_> = path.split(".").collect(); let split_path: Vec<_> = path.split(".").collect();
@ -387,19 +384,13 @@ impl Value {
Value::Object(o) => { Value::Object(o) => {
o.entries.insert( o.entries.insert(
split_path[idx + 1].to_string(), split_path[idx + 1].to_string(),
Spanned { Tagged::from_item(new_value, span),
item: new_value,
span,
},
); );
} }
_ => {} _ => {}
} }
return Some(Spanned { return Some(Tagged::from_item(new_obj, span));
item: new_obj,
span,
});
} else { } else {
match next.item { match next.item {
Value::Object(ref mut o) => { Value::Object(ref mut o) => {
@ -422,7 +413,7 @@ impl Value {
span: Span, span: Span,
path: &str, path: &str,
replaced_value: Value, replaced_value: Value,
) -> Option<Spanned<Value>> { ) -> Option<Tagged<Value>> {
let mut new_obj = self.clone(); let mut new_obj = self.clone();
let split_path: Vec<_> = path.split(".").collect(); let split_path: Vec<_> = path.split(".").collect();
@ -433,14 +424,8 @@ impl Value {
match current.entries.get_mut(split_path[idx]) { match current.entries.get_mut(split_path[idx]) {
Some(next) => { Some(next) => {
if idx == (split_path.len() - 1) { if idx == (split_path.len() - 1) {
*next = Spanned { *next = Tagged::from_item(replaced_value, span);
item: replaced_value, return Some(Tagged::from_item(new_obj, span));
span,
};
return Some(Spanned {
item: new_obj,
span,
});
} else { } else {
match next.item { match next.item {
Value::Object(ref mut o) => { Value::Object(ref mut o) => {
@ -522,7 +507,7 @@ impl Value {
} }
} }
crate fn as_pair(&self) -> Result<(Spanned<Value>, Spanned<Value>), ShellError> { crate fn as_pair(&self) -> Result<(Tagged<Value>, Tagged<Value>), ShellError> {
match self { match self {
Value::List(list) if list.len() == 2 => Ok((list[0].clone(), list[1].clone())), Value::List(list) if list.len() == 2 => Ok((list[0].clone(), list[1].clone())),
other => Err(ShellError::string(format!( other => Err(ShellError::string(format!(
@ -616,8 +601,8 @@ impl Value {
} }
} }
crate fn select_fields(obj: &Value, fields: &[String], span: impl Into<Span>) -> Spanned<Value> { crate fn select_fields(obj: &Value, fields: &[String], span: impl Into<Span>) -> Tagged<Value> {
let mut out = SpannedDictBuilder::new(span); let mut out = TaggedDictBuilder::new(span);
let descs = obj.data_descriptors(); let descs = obj.data_descriptors();
@ -628,11 +613,11 @@ crate fn select_fields(obj: &Value, fields: &[String], span: impl Into<Span>) ->
} }
} }
out.into_spanned_value() out.into_tagged_value()
} }
crate fn reject_fields(obj: &Value, fields: &[String], span: impl Into<Span>) -> Spanned<Value> { crate fn reject_fields(obj: &Value, fields: &[String], span: impl Into<Span>) -> Tagged<Value> {
let mut out = SpannedDictBuilder::new(span); let mut out = TaggedDictBuilder::new(span);
let descs = obj.data_descriptors(); let descs = obj.data_descriptors();
@ -643,7 +628,7 @@ crate fn reject_fields(obj: &Value, fields: &[String], span: impl Into<Span>) ->
} }
} }
out.into_spanned_value() out.into_tagged_value()
} }
#[allow(unused)] #[allow(unused)]

View file

@ -16,10 +16,10 @@ const APP_INFO: AppInfo = AppInfo {
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
struct Config { struct Config {
#[serde(flatten)] #[serde(flatten)]
extra: IndexMap<String, Spanned<Value>>, extra: IndexMap<String, Tagged<Value>>,
} }
crate fn write_config(config: &IndexMap<String, Spanned<Value>>) -> Result<(), ShellError> { crate fn write_config(config: &IndexMap<String, Tagged<Value>>) -> Result<(), ShellError> {
let location = app_root(AppDataType::UserConfig, &APP_INFO) let location = app_root(AppDataType::UserConfig, &APP_INFO)
.map_err(|err| ShellError::string(&format!("Couldn't open config file:\n{}", err)))?; .map_err(|err| ShellError::string(&format!("Couldn't open config file:\n{}", err)))?;
@ -35,7 +35,7 @@ crate fn write_config(config: &IndexMap<String, Spanned<Value>>) -> Result<(), S
Ok(()) Ok(())
} }
crate fn config(span: impl Into<Span>) -> Result<IndexMap<String, Spanned<Value>>, ShellError> { crate fn config(span: impl Into<Span>) -> Result<IndexMap<String, Tagged<Value>>, ShellError> {
let span = span.into(); let span = span.into();
let location = app_root(AppDataType::UserConfig, &APP_INFO) let location = app_root(AppDataType::UserConfig, &APP_INFO)
@ -47,7 +47,7 @@ crate fn config(span: impl Into<Span>) -> Result<IndexMap<String, Spanned<Value>
trace!("config file = {}", filename.display()); trace!("config file = {}", filename.display());
let contents = fs::read_to_string(filename) let contents = fs::read_to_string(filename)
.map(|v| v.spanned(span)) .map(|v| v.tagged(span))
.map_err(|err| ShellError::string(&format!("Couldn't read config file:\n{}", err)))?; .map_err(|err| ShellError::string(&format!("Couldn't read config file:\n{}", err)))?;
let parsed: Config = toml::from_str(&contents) let parsed: Config = toml::from_str(&contents)

View file

@ -9,7 +9,7 @@ use std::fmt;
#[derive(Debug, Default, Eq, PartialEq, Serialize, Deserialize, Clone, new)] #[derive(Debug, Default, Eq, PartialEq, Serialize, Deserialize, Clone, new)]
pub struct Dictionary { pub struct Dictionary {
pub entries: IndexMap<String, Spanned<Value>>, pub entries: IndexMap<String, Tagged<Value>>,
} }
impl PartialOrd for Dictionary { impl PartialOrd for Dictionary {
@ -28,8 +28,8 @@ impl PartialOrd for Dictionary {
} }
} }
impl From<IndexMap<String, Spanned<Value>>> for Dictionary { impl From<IndexMap<String, Tagged<Value>>> for Dictionary {
fn from(input: IndexMap<String, Spanned<Value>>) -> Dictionary { fn from(input: IndexMap<String, Tagged<Value>>) -> Dictionary {
let mut out = IndexMap::default(); let mut out = IndexMap::default();
for (key, value) in input { for (key, value) in input {
@ -79,7 +79,7 @@ impl Dictionary {
} }
} }
crate fn get_data_by_key(&self, name: &str) -> Option<&Spanned<Value>> { crate fn get_data_by_key(&self, name: &str) -> Option<&Tagged<Value>> {
match self match self
.entries .entries
.iter() .iter()
@ -101,72 +101,71 @@ impl Dictionary {
} }
} }
pub struct SpannedListBuilder { pub struct TaggedListBuilder {
span: Span, span: Span,
list: Vec<Spanned<Value>>, list: Vec<Tagged<Value>>,
} }
impl SpannedListBuilder { impl TaggedListBuilder {
pub fn new(span: impl Into<Span>) -> SpannedListBuilder { pub fn new(span: impl Into<Span>) -> TaggedListBuilder {
SpannedListBuilder { TaggedListBuilder {
span: span.into(), span: span.into(),
list: vec![], list: vec![],
} }
} }
pub fn push(&mut self, value: impl Into<Value>) { pub fn push(&mut self, value: impl Into<Value>) {
self.list.push(value.into().spanned(self.span)); self.list.push(value.into().tagged(self.span));
} }
pub fn insert_spanned(&mut self, value: impl Into<Spanned<Value>>) { pub fn insert_tagged(&mut self, value: impl Into<Tagged<Value>>) {
self.list.push(value.into()); self.list.push(value.into());
} }
pub fn into_spanned_value(self) -> Spanned<Value> { pub fn into_tagged_value(self) -> Tagged<Value> {
Value::List(self.list).spanned(self.span) Value::List(self.list).tagged(self.span)
} }
} }
impl From<SpannedListBuilder> for Spanned<Value> { impl From<TaggedListBuilder> for Tagged<Value> {
fn from(input: SpannedListBuilder) -> Spanned<Value> { fn from(input: TaggedListBuilder) -> Tagged<Value> {
input.into_spanned_value() input.into_tagged_value()
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub struct SpannedDictBuilder { pub struct TaggedDictBuilder {
span: Span, span: Span,
dict: IndexMap<String, Spanned<Value>>, dict: IndexMap<String, Tagged<Value>>,
} }
impl SpannedDictBuilder { impl TaggedDictBuilder {
pub fn new(span: impl Into<Span>) -> SpannedDictBuilder { pub fn new(span: impl Into<Span>) -> TaggedDictBuilder {
SpannedDictBuilder { TaggedDictBuilder {
span: span.into(), span: span.into(),
dict: IndexMap::default(), dict: IndexMap::default(),
} }
} }
pub fn insert(&mut self, key: impl Into<String>, value: impl Into<Value>) { pub fn insert(&mut self, key: impl Into<String>, value: impl Into<Value>) {
self.dict self.dict.insert(key.into(), value.into().tagged(self.span));
.insert(key.into(), value.into().spanned(self.span));
} }
pub fn insert_spanned(&mut self, key: impl Into<String>, value: impl Into<Spanned<Value>>) { pub fn insert_tagged(&mut self, key: impl Into<String>, value: impl Into<Tagged<Value>>) {
self.dict.insert(key.into(), value.into()); self.dict.insert(key.into(), value.into());
} }
pub fn into_spanned_value(self) -> Spanned<Value> { pub fn into_tagged_value(self) -> Tagged<Value> {
self.into_spanned_dict().map(Value::Object) self.into_tagged_dict().map(Value::Object)
} }
pub fn into_spanned_dict(self) -> Spanned<Dictionary> { pub fn into_tagged_dict(self) -> Tagged<Dictionary> {
Dictionary { entries: self.dict }.spanned(self.span) Dictionary { entries: self.dict }.tagged(self.span)
} }
} }
impl From<SpannedDictBuilder> for Spanned<Value> { impl From<TaggedDictBuilder> for Tagged<Value> {
fn from(input: SpannedDictBuilder) -> Spanned<Value> { fn from(input: TaggedDictBuilder) -> Tagged<Value> {
input.into_spanned_value() input.into_tagged_value()
} }
} }

View file

@ -1,5 +1,5 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{SpannedDictBuilder, Value}; use crate::object::{TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
#[derive(Debug)] #[derive(Debug)]
@ -12,8 +12,8 @@ pub enum FileType {
crate fn dir_entry_dict( crate fn dir_entry_dict(
entry: &std::fs::DirEntry, entry: &std::fs::DirEntry,
span: impl Into<Span>, span: impl Into<Span>,
) -> Result<Spanned<Value>, ShellError> { ) -> Result<Tagged<Value>, ShellError> {
let mut dict = SpannedDictBuilder::new(span); let mut dict = TaggedDictBuilder::new(span);
let filename = entry.file_name(); let filename = entry.file_name();
dict.insert("name", Value::string(filename.to_string_lossy())); dict.insert("name", Value::string(filename.to_string_lossy()));
@ -50,5 +50,5 @@ crate fn dir_entry_dict(
Err(_) => {} Err(_) => {}
} }
Ok(dict.into_spanned_value()) Ok(dict.into_tagged_value())
} }

View file

@ -13,11 +13,10 @@ impl From<String> for Value {
} }
} }
impl<T: Into<Value>> Spanned<T> { impl<T: Into<Value>> Tagged<T> {
pub fn into_spanned_value(self) -> Spanned<Value> { pub fn into_tagged_value(self) -> Tagged<Value> {
let Spanned { item, span } = self; let value_span = self.span();
let value = self.item.into();
let value = item.into(); value.tagged(value_span)
value.spanned(span)
} }
} }

View file

@ -9,33 +9,27 @@ use uuid::Uuid;
new, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash, Getters, new, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash, Getters,
)] )]
#[get = "crate"] #[get = "crate"]
pub struct Spanned<T> { pub struct Tagged<T> {
pub span: Span, pub tag: Tag,
pub item: T, pub item: T,
} }
impl<T> Spanned<T> { pub trait TaggedItem: Sized {
pub fn spanned(self, span: impl Into<Span>) -> Spanned<T> { fn tagged(self, span: impl Into<Span>) -> Tagged<Self> {
Spanned::from_item(self.item, span.into()) Tagged::from_item(self, span.into())
}
}
pub trait SpannedItem: Sized {
fn spanned(self, span: impl Into<Span>) -> Spanned<Self> {
Spanned::from_item(self, span.into())
} }
// For now, this is a temporary facility. In many cases, there are other useful spans that we // 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 // 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. // have the infrastructure to make that work.
fn spanned_unknown(self) -> Spanned<Self> { fn tagged_unknown(self) -> Tagged<Self> {
Spanned::from_item(self, (0, 0)) Tagged::from_item(self, (0, 0))
} }
} }
impl<T> SpannedItem for T {} impl<T> TaggedItem for T {}
impl<T> std::ops::Deref for Spanned<T> { impl<T> std::ops::Deref for Tagged<T> {
type Target = T; type Target = T;
fn deref(&self) -> &T { fn deref(&self) -> &T {
@ -43,58 +37,43 @@ impl<T> std::ops::Deref for Spanned<T> {
} }
} }
impl<T> Spanned<T> { impl<T> Tagged<T> {
crate fn from_item(item: T, span: impl Into<Span>) -> Spanned<T> { pub fn tagged(self, span: impl Into<Span>) -> Tagged<T> {
Spanned { Tagged::from_item(self.item, span.into())
span: span.into(), }
pub fn from_item(item: T, span: impl Into<Span>) -> Tagged<T> {
Tagged {
item, item,
tag: Tag { span: span.into() },
} }
} }
pub fn map<U>(self, input: impl FnOnce(T) -> U) -> Spanned<U> { pub fn map<U>(self, input: impl FnOnce(T) -> U) -> Tagged<U> {
let Spanned { span, item } = self; let span = self.span();
let mapped = input(item); let mapped = input(self.item);
Spanned { span, item: mapped } Tagged::from_item(mapped, span)
} }
crate fn copy_span<U>(&self, output: U) -> Spanned<U> { crate fn copy_span<U>(&self, output: U) -> Tagged<U> {
let Spanned { span, .. } = self; let span = self.span();
Spanned { Tagged::from_item(output, span)
span: *span,
item: output,
}
} }
pub fn source(&self, source: &Text) -> Text { pub fn source(&self, source: &Text) -> Text {
Text::from(self.span().slice(source)) Text::from(self.span().slice(source))
} }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, Hash)] pub fn span(&self) -> Span {
pub struct Span { self.tag.span
crate start: usize,
crate end: usize,
pub source: Option<Uuid>,
}
impl From<Option<Span>> for Span {
fn from(input: Option<Span>) -> Span {
match input {
None => Span {
start: 0,
end: 0,
source: None,
},
Some(span) => span,
}
} }
} }
impl<T> From<&Spanned<T>> for Span { impl<T> From<&Tagged<T>> for Span {
fn from(input: &Spanned<T>) -> Span { fn from(input: &Tagged<T>) -> Span {
input.span input.span()
} }
} }
@ -144,6 +123,33 @@ impl From<&std::ops::Range<usize>> for Span {
} }
} }
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, Hash, Getters,
)]
pub struct Tag {
pub span: Span,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
pub struct Span {
crate start: usize,
crate end: usize,
pub source: Option<Uuid>,
}
impl From<Option<Span>> for Span {
fn from(input: Option<Span>) -> Span {
match input {
None => Span {
start: 0,
end: 0,
source: None,
},
Some(span) => span,
}
}
}
impl Span { impl Span {
pub fn unknown() -> Span { pub fn unknown() -> Span {
Span { Span {

View file

@ -1,10 +1,10 @@
use crate::object::{SpannedDictBuilder, Value}; use crate::object::{TaggedDictBuilder, Value};
use crate::prelude::*; use crate::prelude::*;
use itertools::join; use itertools::join;
use sysinfo::ProcessExt; use sysinfo::ProcessExt;
crate fn process_dict(proc: &sysinfo::Process, span: impl Into<Span>) -> Spanned<Value> { crate fn process_dict(proc: &sysinfo::Process, span: impl Into<Span>) -> Tagged<Value> {
let mut dict = SpannedDictBuilder::new(span); let mut dict = TaggedDictBuilder::new(span);
let cmd = proc.cmd(); let cmd = proc.cmd();
@ -25,5 +25,5 @@ crate fn process_dict(proc: &sysinfo::Process, span: impl Into<Span>) -> Spanned
_ => dict.insert("name", cmd_value), _ => dict.insert("name", cmd_value),
} }
dict.into_spanned_value() dict.into_tagged_value()
} }

View file

@ -12,19 +12,19 @@ pub trait Type: std::fmt::Debug + Send {
} }
pub trait ExtractType: Sized { pub trait ExtractType: Sized {
fn extract(value: &Spanned<Value>) -> Result<Self, ShellError>; fn extract(value: &Tagged<Value>) -> Result<Self, ShellError>;
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError>; fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError>;
fn syntax_type() -> hir::SyntaxType { fn syntax_type() -> hir::SyntaxType {
hir::SyntaxType::Any hir::SyntaxType::Any
} }
} }
impl<T: ExtractType> ExtractType for Spanned<T> { impl<T: ExtractType> ExtractType for Tagged<T> {
fn extract(value: &Spanned<Value>) -> Result<Spanned<T>, ShellError> { fn extract(value: &Tagged<Value>) -> Result<Tagged<T>, ShellError> {
Ok(T::extract(value)?.spanned(value.span)) Ok(T::extract(value)?.tagged(value.span()))
} }
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> { fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError> {
T::check(value) T::check(value)
} }
@ -37,19 +37,19 @@ impl<T: ExtractType> ExtractType for Spanned<T> {
pub struct Any; pub struct Any;
impl Type for Any { impl Type for Any {
type Extractor = Spanned<Value>; type Extractor = Tagged<Value>;
fn name(&self) -> &'static str { fn name(&self) -> &'static str {
"Any" "Any"
} }
} }
impl ExtractType for Spanned<Value> { impl ExtractType for Tagged<Value> {
fn extract(value: &Spanned<Value>) -> Result<Self, ShellError> { fn extract(value: &Tagged<Value>) -> Result<Self, ShellError> {
Ok(value.clone()) Ok(value.clone())
} }
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> { fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError> {
Ok(value) Ok(value)
} }
} }
@ -59,23 +59,23 @@ impl ExtractType for std::path::PathBuf {
hir::SyntaxType::Path hir::SyntaxType::Path
} }
fn extract(value: &'a Spanned<Value>) -> Result<std::path::PathBuf, ShellError> { fn extract(value: &'a Tagged<Value>) -> Result<std::path::PathBuf, ShellError> {
match &value { match &value {
Spanned { Tagged {
item: Value::Primitive(Primitive::String(p)), item: Value::Primitive(Primitive::String(p)),
.. ..
} => Ok(PathBuf::from(p)), } => Ok(PathBuf::from(p)),
other => Err(ShellError::type_error("Path", other.spanned_type_name())), other => Err(ShellError::type_error("Path", other.tagged_type_name())),
} }
} }
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> { fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError> {
match &value { match &value {
v @ Spanned { v @ Tagged {
item: Value::Primitive(Primitive::Path(_)), item: Value::Primitive(Primitive::Path(_)),
.. ..
} => Ok(v), } => Ok(v),
other => Err(ShellError::type_error("Path", other.spanned_type_name())), other => Err(ShellError::type_error("Path", other.tagged_type_name())),
} }
} }
} }
@ -92,23 +92,23 @@ impl Type for Integer {
} }
impl ExtractType for i64 { impl ExtractType for i64 {
fn extract(value: &Spanned<Value>) -> Result<i64, ShellError> { fn extract(value: &Tagged<Value>) -> Result<i64, ShellError> {
match value { match value {
&Spanned { &Tagged {
item: Value::Primitive(Primitive::Int(int)), item: Value::Primitive(Primitive::Int(int)),
.. ..
} => Ok(int), } => Ok(int),
other => Err(ShellError::type_error("Integer", other.spanned_type_name())), other => Err(ShellError::type_error("Integer", other.tagged_type_name())),
} }
} }
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> { fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError> {
match value { match value {
v @ Spanned { v @ Tagged {
item: Value::Primitive(Primitive::Int(_)), item: Value::Primitive(Primitive::Int(_)),
.. ..
} => Ok(v), } => Ok(v),
other => Err(ShellError::type_error("Integer", other.spanned_type_name())), other => Err(ShellError::type_error("Integer", other.tagged_type_name())),
} }
} }
} }
@ -125,23 +125,23 @@ impl Type for NuString {
} }
impl ExtractType for String { impl ExtractType for String {
fn extract(value: &Spanned<Value>) -> Result<String, ShellError> { fn extract(value: &Tagged<Value>) -> Result<String, ShellError> {
match value { match value {
Spanned { Tagged {
item: Value::Primitive(Primitive::String(string)), item: Value::Primitive(Primitive::String(string)),
.. ..
} => Ok(string.clone()), } => Ok(string.clone()),
other => Err(ShellError::type_error("String", other.spanned_type_name())), other => Err(ShellError::type_error("String", other.tagged_type_name())),
} }
} }
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> { fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError> {
match value { match value {
v @ Spanned { v @ Tagged {
item: Value::Primitive(Primitive::String(_)), item: Value::Primitive(Primitive::String(_)),
.. ..
} => Ok(v), } => Ok(v),
other => Err(ShellError::type_error("String", other.spanned_type_name())), other => Err(ShellError::type_error("String", other.tagged_type_name())),
} }
} }
} }
@ -158,23 +158,23 @@ impl Type for Block {
} }
impl ExtractType for value::Block { impl ExtractType for value::Block {
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> { fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError> {
match value { match value {
v @ Spanned { v @ Tagged {
item: Value::Block(_), item: Value::Block(_),
.. ..
} => Ok(v), } => Ok(v),
other => Err(ShellError::type_error("Block", other.spanned_type_name())), other => Err(ShellError::type_error("Block", other.tagged_type_name())),
} }
} }
fn extract(value: &Spanned<Value>) -> Result<value::Block, ShellError> { fn extract(value: &Tagged<Value>) -> Result<value::Block, ShellError> {
match value { match value {
Spanned { Tagged {
item: Value::Block(block), item: Value::Block(block),
.. ..
} => Ok(block.clone()), } => Ok(block.clone()),
other => Err(ShellError::type_error("Block", other.spanned_type_name())), other => Err(ShellError::type_error("Block", other.tagged_type_name())),
} }
} }
} }

View file

@ -12,7 +12,6 @@ crate use parse::flag::Flag;
crate use parse::operator::Operator; crate use parse::operator::Operator;
crate use parse::parser::{nom_input, pipeline}; crate use parse::parser::{nom_input, pipeline};
crate use parse::pipeline::{Pipeline, PipelineElement}; crate use parse::pipeline::{Pipeline, PipelineElement};
pub use parse::span::{Span, Spanned, SpannedItem};
crate use parse::text::Text; crate use parse::text::Text;
crate use parse::token_tree::{DelimitedNode, Delimiter, PathNode, TokenNode}; crate use parse::token_tree::{DelimitedNode, Delimiter, PathNode, TokenNode};
crate use parse::tokens::{RawToken, Token}; crate use parse::tokens::{RawToken, Token};

View file

@ -4,7 +4,9 @@ crate mod binary;
crate mod named; crate mod named;
crate mod path; crate mod path;
use crate::parser::{Span, Spanned, Unit}; use crate::parser::Unit;
use crate::Span;
use crate::Tagged;
use derive_new::new; use derive_new::new;
use getset::Getters; use getset::Getters;
@ -14,7 +16,7 @@ crate use binary::Binary;
crate use named::NamedArguments; crate use named::NamedArguments;
crate use path::Path; crate use path::Path;
pub fn path(head: impl Into<Expression>, tail: Vec<Spanned<impl Into<String>>>) -> Path { pub fn path(head: impl Into<Expression>, tail: Vec<Tagged<impl Into<String>>>) -> Path {
Path::new( Path::new(
head.into(), head.into(),
tail.into_iter() tail.into_iter()
@ -58,48 +60,48 @@ impl RawExpression {
} }
} }
pub type Expression = Spanned<RawExpression>; pub type Expression = Tagged<RawExpression>;
impl Expression { impl Expression {
fn int(i: impl Into<i64>, span: impl Into<Span>) -> Expression { fn int(i: impl Into<i64>, span: impl Into<Span>) -> Expression {
Spanned::from_item(RawExpression::Literal(Literal::Integer(i.into())), span) Tagged::from_item(RawExpression::Literal(Literal::Integer(i.into())), span)
} }
fn size(i: impl Into<i64>, unit: impl Into<Unit>, span: impl Into<Span>) -> Expression { fn size(i: impl Into<i64>, unit: impl Into<Unit>, span: impl Into<Span>) -> Expression {
Spanned::from_item( Tagged::from_item(
RawExpression::Literal(Literal::Size(i.into(), unit.into())), RawExpression::Literal(Literal::Size(i.into(), unit.into())),
span, span,
) )
} }
fn string(inner: impl Into<Span>, outer: impl Into<Span>) -> Expression { fn string(inner: impl Into<Span>, outer: impl Into<Span>) -> Expression {
Spanned::from_item( Tagged::from_item(
RawExpression::Literal(Literal::String(inner.into())), RawExpression::Literal(Literal::String(inner.into())),
outer.into(), outer.into(),
) )
} }
fn bare(span: impl Into<Span>) -> Expression { fn bare(span: impl Into<Span>) -> Expression {
Spanned::from_item(RawExpression::Literal(Literal::Bare), span.into()) Tagged::from_item(RawExpression::Literal(Literal::Bare), span.into())
} }
fn variable(inner: impl Into<Span>, outer: impl Into<Span>) -> Expression { fn variable(inner: impl Into<Span>, outer: impl Into<Span>) -> Expression {
Spanned::from_item( Tagged::from_item(
RawExpression::Variable(Variable::Other(inner.into())), RawExpression::Variable(Variable::Other(inner.into())),
outer.into(), outer.into(),
) )
} }
fn it_variable(inner: impl Into<Span>, outer: impl Into<Span>) -> Expression { fn it_variable(inner: impl Into<Span>, outer: impl Into<Span>) -> Expression {
Spanned::from_item( Tagged::from_item(
RawExpression::Variable(Variable::It(inner.into())), RawExpression::Variable(Variable::It(inner.into())),
outer.into(), outer.into(),
) )
} }
} }
impl From<Spanned<Path>> for Expression { impl From<Tagged<Path>> for Expression {
fn from(path: Spanned<Path>) -> Expression { fn from(path: Tagged<Path>) -> Expression {
path.map(|p| RawExpression::Path(Box::new(p))) path.map(|p| RawExpression::Path(Box::new(p)))
} }
} }

View file

@ -3,26 +3,26 @@ use crate::Text;
pub fn baseline_parse_single_token(token: &Token, source: &Text) -> hir::Expression { pub fn baseline_parse_single_token(token: &Token, source: &Text) -> hir::Expression {
match *token.item() { match *token.item() {
RawToken::Integer(int) => hir::Expression::int(int, token.span), RawToken::Integer(int) => hir::Expression::int(int, token.span()),
RawToken::Size(int, unit) => hir::Expression::size(int, unit, token.span), RawToken::Size(int, unit) => hir::Expression::size(int, unit, token.span()),
RawToken::String(span) => hir::Expression::string(span, token.span), RawToken::String(span) => hir::Expression::string(span, token.span()),
RawToken::Variable(span) if span.slice(source) == "it" => { RawToken::Variable(span) if span.slice(source) == "it" => {
hir::Expression::it_variable(span, token.span) hir::Expression::it_variable(span, token.span())
} }
RawToken::Variable(span) => hir::Expression::variable(span, token.span), RawToken::Variable(span) => hir::Expression::variable(span, token.span()),
RawToken::Bare => hir::Expression::bare(token.span), RawToken::Bare => hir::Expression::bare(token.span()),
} }
} }
pub fn baseline_parse_token_as_string(token: &Token, source: &Text) -> hir::Expression { pub fn baseline_parse_token_as_string(token: &Token, source: &Text) -> hir::Expression {
match *token.item() { match *token.item() {
RawToken::Variable(span) if span.slice(source) == "it" => { RawToken::Variable(span) if span.slice(source) == "it" => {
hir::Expression::it_variable(span, token.span) hir::Expression::it_variable(span, token.span())
} }
RawToken::Variable(span) => hir::Expression::variable(span, token.span), RawToken::Variable(span) => hir::Expression::variable(span, token.span()),
RawToken::Integer(_) => hir::Expression::bare(token.span), RawToken::Integer(_) => hir::Expression::bare(token.span()),
RawToken::Size(_, _) => hir::Expression::bare(token.span), RawToken::Size(_, _) => hir::Expression::bare(token.span()),
RawToken::Bare => hir::Expression::bare(token.span), RawToken::Bare => hir::Expression::bare(token.span()),
RawToken::String(span) => hir::Expression::string(span, token.span), RawToken::String(span) => hir::Expression::string(span, token.span()),
} }
} }

View file

@ -3,9 +3,9 @@ use crate::parser::registry::CommandRegistry;
use crate::parser::{ use crate::parser::{
hir, hir,
hir::{baseline_parse_single_token, baseline_parse_token_as_string}, hir::{baseline_parse_single_token, baseline_parse_token_as_string},
DelimitedNode, Delimiter, PathNode, RawToken, Span, Spanned, TokenNode, DelimitedNode, Delimiter, PathNode, RawToken, TokenNode,
}; };
use crate::{SpannedItem, Text}; use crate::{Span, Tag, Tagged, TaggedItem, Text};
use derive_new::new; use derive_new::new;
use log::trace; use log::trace;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
@ -61,7 +61,7 @@ pub fn baseline_parse_next_expr(
(SyntaxType::Path, token) => { (SyntaxType::Path, token) => {
return Err(ShellError::type_error( return Err(ShellError::type_error(
"Path", "Path",
token.type_name().spanned(token.span()), token.type_name().tagged(token.span()),
)) ))
} }
@ -84,7 +84,7 @@ pub fn baseline_parse_next_expr(
return Err(ShellError::maybe_labeled_error( return Err(ShellError::maybe_labeled_error(
"Expected something after an operator", "Expected something after an operator",
"operator", "operator",
Some(op.span), Some(op.span()),
)) ))
} }
Some(token) => baseline_parse_semantic_token(token, registry, source)?, Some(token) => baseline_parse_semantic_token(token, registry, source)?,
@ -94,25 +94,25 @@ pub fn baseline_parse_next_expr(
match syntax_type { match syntax_type {
SyntaxType::Any => { SyntaxType::Any => {
let span = (first.span.start, second.span.end); let span = (first.span().start, second.span().end);
let binary = hir::Binary::new(first, op, second); let binary = hir::Binary::new(first, op, second);
let binary = hir::RawExpression::Binary(Box::new(binary)); let binary = hir::RawExpression::Binary(Box::new(binary));
let binary = Spanned::from_item(binary, span); let binary = Tagged::from_item(binary, span);
Ok(binary) Ok(binary)
} }
SyntaxType::Block => { SyntaxType::Block => {
let span = (first.span.start, second.span.end); let span = (first.span().start, second.span().end);
let path: Spanned<hir::RawExpression> = match first { let path: Tagged<hir::RawExpression> = match first {
Spanned { Tagged {
item: hir::RawExpression::Literal(hir::Literal::Bare), item: hir::RawExpression::Literal(hir::Literal::Bare),
span, tag: Tag { span },
} => { } => {
let string = Spanned::from_item(span.slice(source).to_string(), span); let string = Tagged::from_item(span.slice(source).to_string(), span);
let path = hir::Path::new( let path = hir::Path::new(
Spanned::from_item( Tagged::from_item(
// TODO: Deal with synthetic nodes that have no representation at all in source // TODO: Deal with synthetic nodes that have no representation at all in source
hir::RawExpression::Variable(hir::Variable::It(Span::from((0, 0)))), hir::RawExpression::Variable(hir::Variable::It(Span::from((0, 0)))),
(0, 0), (0, 0),
@ -120,18 +120,15 @@ pub fn baseline_parse_next_expr(
vec![string], vec![string],
); );
let path = hir::RawExpression::Path(Box::new(path)); let path = hir::RawExpression::Path(Box::new(path));
Spanned { Tagged::from_item(path, first.span())
item: path,
span: first.span,
}
} }
Spanned { Tagged {
item: hir::RawExpression::Literal(hir::Literal::String(inner)), item: hir::RawExpression::Literal(hir::Literal::String(inner)),
span, tag: Tag { span },
} => { } => {
let string = Spanned::from_item(inner.slice(source).to_string(), span); let string = Tagged::from_item(inner.slice(source).to_string(), span);
let path = hir::Path::new( let path = hir::Path::new(
Spanned::from_item( Tagged::from_item(
// TODO: Deal with synthetic nodes that have no representation at all in source // TODO: Deal with synthetic nodes that have no representation at all in source
hir::RawExpression::Variable(hir::Variable::It(Span::from((0, 0)))), hir::RawExpression::Variable(hir::Variable::It(Span::from((0, 0)))),
(0, 0), (0, 0),
@ -139,16 +136,16 @@ pub fn baseline_parse_next_expr(
vec![string], vec![string],
); );
let path = hir::RawExpression::Path(Box::new(path)); let path = hir::RawExpression::Path(Box::new(path));
Spanned { Tagged::from_item(path, first.span())
item: path,
span: first.span,
}
} }
Spanned { Tagged {
item: hir::RawExpression::Variable(..), item: hir::RawExpression::Variable(..),
.. ..
} => first, } => first,
Spanned { span, item } => { Tagged {
tag: Tag { span },
item,
} => {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"The first part of an un-braced block must be a column name", "The first part of an un-braced block must be a column name",
item.type_name(), item.type_name(),
@ -159,10 +156,10 @@ pub fn baseline_parse_next_expr(
let binary = hir::Binary::new(path, op, second); let binary = hir::Binary::new(path, op, second);
let binary = hir::RawExpression::Binary(Box::new(binary)); let binary = hir::RawExpression::Binary(Box::new(binary));
let binary = Spanned::from_item(binary, span); let binary = Tagged::from_item(binary, span);
let block = hir::RawExpression::Block(vec![binary]); let block = hir::RawExpression::Block(vec![binary]);
let block = Spanned::from_item(block, span); let block = Tagged::from_item(block, span);
Ok(block) Ok(block)
} }
@ -196,7 +193,7 @@ pub fn baseline_parse_semantic_token(
} }
pub fn baseline_parse_delimited( pub fn baseline_parse_delimited(
token: &Spanned<DelimitedNode>, token: &Tagged<DelimitedNode>,
registry: &dyn CommandRegistry, registry: &dyn CommandRegistry,
source: &Text, source: &Text,
) -> Result<hir::Expression, ShellError> { ) -> Result<hir::Expression, ShellError> {
@ -207,7 +204,7 @@ pub fn baseline_parse_delimited(
baseline_parse_tokens(&mut TokensIterator::new(children), registry, source)?; baseline_parse_tokens(&mut TokensIterator::new(children), registry, source)?;
let expr = hir::RawExpression::Block(exprs); let expr = hir::RawExpression::Block(exprs);
Ok(Spanned::from_item(expr, token.span())) Ok(Tagged::from_item(expr, token.span()))
} }
Delimiter::Paren => unimplemented!(), Delimiter::Paren => unimplemented!(),
Delimiter::Square => unimplemented!(), Delimiter::Square => unimplemented!(),
@ -215,7 +212,7 @@ pub fn baseline_parse_delimited(
} }
pub fn baseline_parse_path( pub fn baseline_parse_path(
token: &Spanned<PathNode>, token: &Tagged<PathNode>,
registry: &dyn CommandRegistry, registry: &dyn CommandRegistry,
source: &Text, source: &Text,
) -> Result<hir::Expression, ShellError> { ) -> Result<hir::Expression, ShellError> {
@ -231,7 +228,7 @@ pub fn baseline_parse_path(
RawToken::Integer(_) | RawToken::Size(..) | RawToken::Variable(_) => { RawToken::Integer(_) | RawToken::Size(..) | RawToken::Variable(_) => {
return Err(ShellError::type_error( return Err(ShellError::type_error(
"String", "String",
token.type_name().spanned(part), token.type_name().tagged(part),
)) ))
} }
}, },
@ -243,10 +240,10 @@ pub fn baseline_parse_path(
} }
.to_string(); .to_string();
tail.push(string.spanned(part)); tail.push(string.tagged(part));
} }
Ok(hir::path(head, tail).spanned(token).into()) Ok(hir::path(head, tail).tagged(token).into())
} }
#[derive(Debug, new)] #[derive(Debug, new)]

View file

@ -1,4 +1,5 @@
use crate::parser::{hir::Expression, Operator, Spanned}; use crate::parser::{hir::Expression, Operator};
use crate::Tagged;
use derive_new::new; use derive_new::new;
use getset::Getters; use getset::Getters;
@ -6,6 +7,6 @@ use getset::Getters;
#[get = "crate"] #[get = "crate"]
pub struct Binary { pub struct Binary {
left: Expression, left: Expression,
op: Spanned<Operator>, op: Tagged<Operator>,
right: Expression, right: Expression,
} }

View file

@ -1,5 +1,6 @@
use crate::parser::hir::Expression; use crate::parser::hir::Expression;
use crate::parser::{Flag, Span}; use crate::parser::Flag;
use crate::Span;
use derive_new::new; use derive_new::new;
use indexmap::IndexMap; use indexmap::IndexMap;
use log::trace; use log::trace;

View file

@ -1,4 +1,5 @@
use crate::parser::{hir::Expression, Spanned}; use crate::parser::hir::Expression;
use crate::Tagged;
use derive_new::new; use derive_new::new;
use getset::Getters; use getset::Getters;
@ -6,5 +7,5 @@ use getset::Getters;
#[get = "crate"] #[get = "crate"]
pub struct Path { pub struct Path {
head: Expression, head: Expression,
tail: Vec<Spanned<String>>, tail: Vec<Tagged<String>>,
} }

View file

@ -4,7 +4,6 @@ crate mod flag;
crate mod operator; crate mod operator;
crate mod parser; crate mod parser;
crate mod pipeline; crate mod pipeline;
crate mod span;
crate mod text; crate mod text;
crate mod token_tree; crate mod token_tree;
crate mod token_tree_builder; crate mod token_tree_builder;

View file

@ -1,4 +1,4 @@
use crate::parser::parse::span::Span; use crate::Span;
use derive_new::new; use derive_new::new;
use language_reporting::{FileName, Location}; use language_reporting::{FileName, Location};

View file

@ -1,4 +1,4 @@
use crate::parser::Span; use crate::Span;
use derive_new::new; use derive_new::new;
use getset::Getters; use getset::Getters;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};

View file

@ -1,9 +1,10 @@
#![allow(unused)] #![allow(unused)]
use crate::parser::parse::{ use crate::parser::parse::{
call_node::*, flag::*, operator::*, pipeline::*, span::*, token_tree::*, token_tree_builder::*, call_node::*, flag::*, operator::*, pipeline::*, token_tree::*, token_tree_builder::*,
tokens::*, unit::*, tokens::*, unit::*,
}; };
use crate::{Span, Tagged};
use nom; use nom;
use nom::branch::*; use nom::branch::*;
use nom::bytes::complete::*; use nom::bytes::complete::*;
@ -67,7 +68,7 @@ fn trace_step<'a, T: Debug>(
} }
} }
pub fn raw_integer(input: NomSpan) -> IResult<NomSpan, Spanned<i64>> { pub fn raw_integer(input: NomSpan) -> IResult<NomSpan, Tagged<i64>> {
let start = input.offset; let start = input.offset;
trace_step(input, "raw_integer", move |input| { trace_step(input, "raw_integer", move |input| {
let (input, neg) = opt(tag("-"))(input)?; let (input, neg) = opt(tag("-"))(input)?;
@ -76,7 +77,7 @@ pub fn raw_integer(input: NomSpan) -> IResult<NomSpan, Spanned<i64>> {
Ok(( Ok((
input, input,
Spanned::from_item(int(num.fragment, neg), (start, end)), Tagged::from_item(int(num.fragment, neg), (start, end)),
)) ))
}) })
} }
@ -85,7 +86,7 @@ pub fn integer(input: NomSpan) -> IResult<NomSpan, TokenNode> {
trace_step(input, "integer", move |input| { trace_step(input, "integer", move |input| {
let (input, int) = raw_integer(input)?; let (input, int) = raw_integer(input)?;
Ok((input, TokenTreeBuilder::spanned_int(*int, int.span))) Ok((input, TokenTreeBuilder::spanned_int(*int, int.span())))
}) })
} }
*/ */
@ -202,7 +203,7 @@ pub fn shorthand(input: NomSpan) -> IResult<NomSpan, TokenNode> {
}) })
} }
pub fn raw_unit(input: NomSpan) -> IResult<NomSpan, Spanned<Unit>> { pub fn raw_unit(input: NomSpan) -> IResult<NomSpan, Tagged<Unit>> {
trace_step(input, "raw_unit", move |input| { trace_step(input, "raw_unit", move |input| {
let start = input.offset; let start = input.offset;
let (input, unit) = alt(( let (input, unit) = alt((
@ -230,7 +231,7 @@ pub fn raw_unit(input: NomSpan) -> IResult<NomSpan, Spanned<Unit>> {
Ok(( Ok((
input, input,
Spanned::from_item(Unit::from(unit.fragment), (start, end)), Tagged::from_item(Unit::from(unit.fragment), (start, end)),
)) ))
}) })
} }
@ -408,7 +409,7 @@ pub fn delimited_brace(input: NomSpan) -> IResult<NomSpan, TokenNode> {
}) })
} }
pub fn raw_call(input: NomSpan) -> IResult<NomSpan, Spanned<CallNode>> { pub fn raw_call(input: NomSpan) -> IResult<NomSpan, Tagged<CallNode>> {
trace_step(input, "raw_call", move |input| { trace_step(input, "raw_call", move |input| {
let left = input.offset; let left = input.offset;
let (input, items) = token_list(input)?; let (input, items) = token_list(input)?;
@ -484,10 +485,10 @@ pub fn pipeline(input: NomSpan) -> IResult<NomSpan, TokenNode> {
} }
fn make_call_list( fn make_call_list(
head: Option<(Spanned<CallNode>, Option<NomSpan>, Option<NomSpan>)>, head: Option<(Tagged<CallNode>, Option<NomSpan>, Option<NomSpan>)>,
items: Vec<( items: Vec<(
Option<NomSpan>, Option<NomSpan>,
Spanned<CallNode>, Tagged<CallNode>,
Option<NomSpan>, Option<NomSpan>,
Option<NomSpan>, Option<NomSpan>,
)>, )>,
@ -701,12 +702,12 @@ mod tests {
fn test_flag() { fn test_flag() {
// assert_leaf! { // assert_leaf! {
// parsers [ flag ] // parsers [ flag ]
// "--hello" -> 0..7 { Flag(Spanned::from_item(FlagKind::Longhand, span(2, 7))) } // "--hello" -> 0..7 { Flag(Tagged::from_item(FlagKind::Longhand, span(2, 7))) }
// } // }
// assert_leaf! { // assert_leaf! {
// parsers [ flag ] // parsers [ flag ]
// "--hello-world" -> 0..13 { Flag(Spanned::from_item(FlagKind::Longhand, span(2, 13))) } // "--hello-world" -> 0..13 { Flag(Tagged::from_item(FlagKind::Longhand, span(2, 13))) }
// } // }
} }
@ -714,7 +715,7 @@ mod tests {
fn test_shorthand() { fn test_shorthand() {
// assert_leaf! { // assert_leaf! {
// parsers [ shorthand ] // parsers [ shorthand ]
// "-alt" -> 0..4 { Flag(Spanned::from_item(FlagKind::Shorthand, span(1, 4))) } // "-alt" -> 0..4 { Flag(Tagged::from_item(FlagKind::Shorthand, span(1, 4))) }
// } // }
} }
@ -1024,7 +1025,7 @@ mod tests {
right: usize, right: usize,
) -> TokenNode { ) -> TokenNode {
let node = DelimitedNode::new(delimiter, children); let node = DelimitedNode::new(delimiter, children);
let spanned = Spanned::from_item(node, (left, right)); let spanned = Tagged::from_item(node, (left, right));
TokenNode::Delimited(spanned) TokenNode::Delimited(spanned)
} }
@ -1033,16 +1034,16 @@ mod tests {
Box::new(head), Box::new(head),
tail.into_iter().map(TokenNode::Token).collect(), tail.into_iter().map(TokenNode::Token).collect(),
); );
let spanned = Spanned::from_item(node, (left, right)); let spanned = Tagged::from_item(node, (left, right));
TokenNode::Path(spanned) TokenNode::Path(spanned)
} }
fn leaf_token(token: RawToken, left: usize, right: usize) -> TokenNode { fn leaf_token(token: RawToken, left: usize, right: usize) -> TokenNode {
TokenNode::Token(Spanned::from_item(token, (left, right))) TokenNode::Token(Tagged::from_item(token, (left, right)))
} }
fn token(token: RawToken, left: usize, right: usize) -> TokenNode { fn token(token: RawToken, left: usize, right: usize) -> TokenNode {
TokenNode::Token(Spanned::from_item(token, (left, right))) TokenNode::Token(Tagged::from_item(token, (left, right)))
} }
fn build<T>(block: CurriedNode<T>) -> T { fn build<T>(block: CurriedNode<T>) -> T {

View file

@ -1,4 +1,5 @@
use crate::parser::{CallNode, Span, Spanned}; use crate::parser::CallNode;
use crate::{Span, Tagged};
use derive_new::new; use derive_new::new;
use getset::Getters; use getset::Getters;
@ -12,7 +13,7 @@ pub struct Pipeline {
pub struct PipelineElement { pub struct PipelineElement {
pub pre_ws: Option<Span>, pub pre_ws: Option<Span>,
#[get = "crate"] #[get = "crate"]
call: Spanned<CallNode>, call: Tagged<CallNode>,
pub post_ws: Option<Span>, pub post_ws: Option<Span>,
pub post_pipe: Option<Span>, pub post_pipe: Option<Span>,
} }

View file

@ -1,6 +1,6 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::parser::parse::{call_node::*, flag::*, operator::*, pipeline::*, span::*, tokens::*}; use crate::parser::parse::{call_node::*, flag::*, operator::*, pipeline::*, tokens::*};
use crate::Text; use crate::{Span, Tagged, Text};
use derive_new::new; use derive_new::new;
use enum_utils::FromStr; use enum_utils::FromStr;
use getset::Getters; use getset::Getters;
@ -10,16 +10,16 @@ use std::fmt;
pub enum TokenNode { pub enum TokenNode {
Token(Token), Token(Token),
#[allow(unused)] #[allow(unused)]
Call(Spanned<CallNode>), Call(Tagged<CallNode>),
Delimited(Spanned<DelimitedNode>), Delimited(Tagged<DelimitedNode>),
Pipeline(Spanned<Pipeline>), Pipeline(Tagged<Pipeline>),
Operator(Spanned<Operator>), Operator(Tagged<Operator>),
Flag(Spanned<Flag>), Flag(Tagged<Flag>),
Member(Span), Member(Span),
Whitespace(Span), Whitespace(Span),
#[allow(unused)] #[allow(unused)]
Error(Spanned<Box<ShellError>>), Error(Tagged<Box<ShellError>>),
Path(Spanned<PathNode>), Path(Tagged<PathNode>),
} }
pub struct DebugTokenNode<'a> { pub struct DebugTokenNode<'a> {
@ -86,16 +86,16 @@ impl From<&TokenNode> for Span {
impl TokenNode { impl TokenNode {
pub fn span(&self) -> Span { pub fn span(&self) -> Span {
match self { match self {
TokenNode::Token(t) => t.span, TokenNode::Token(t) => t.span(),
TokenNode::Call(s) => s.span, TokenNode::Call(s) => s.span(),
TokenNode::Delimited(s) => s.span, TokenNode::Delimited(s) => s.span(),
TokenNode::Pipeline(s) => s.span, TokenNode::Pipeline(s) => s.span(),
TokenNode::Operator(s) => s.span, TokenNode::Operator(s) => s.span(),
TokenNode::Flag(s) => s.span, TokenNode::Flag(s) => s.span(),
TokenNode::Member(s) => *s, TokenNode::Member(s) => *s,
TokenNode::Whitespace(s) => *s, TokenNode::Whitespace(s) => *s,
TokenNode::Error(s) => s.span, TokenNode::Error(s) => s.span(),
TokenNode::Path(s) => s.span, TokenNode::Path(s) => s.span(),
} }
} }
@ -129,7 +129,7 @@ impl TokenNode {
pub fn is_bare(&self) -> bool { pub fn is_bare(&self) -> bool {
match self { match self {
TokenNode::Token(Spanned { TokenNode::Token(Tagged {
item: RawToken::Bare, item: RawToken::Bare,
.. ..
}) => true, }) => true,
@ -137,10 +137,10 @@ impl TokenNode {
} }
} }
crate fn as_flag(&self, value: &str, source: &Text) -> Option<Spanned<Flag>> { crate fn as_flag(&self, value: &str, source: &Text) -> Option<Tagged<Flag>> {
match self { match self {
TokenNode::Flag( TokenNode::Flag(
flag @ Spanned { flag @ Tagged {
item: Flag { .. }, .. item: Flag { .. }, ..
}, },
) if value == flag.name().slice(source) => Some(*flag), ) if value == flag.name().slice(source) => Some(*flag),
@ -150,7 +150,7 @@ impl TokenNode {
pub fn as_pipeline(&self) -> Result<Pipeline, ShellError> { pub fn as_pipeline(&self) -> Result<Pipeline, ShellError> {
match self { match self {
TokenNode::Pipeline(Spanned { item, .. }) => Ok(item.clone()), TokenNode::Pipeline(Tagged { item, .. }) => Ok(item.clone()),
_ => Err(ShellError::string("unimplemented")), _ => Err(ShellError::string("unimplemented")),
} }
} }

View file

@ -4,11 +4,11 @@ use crate::prelude::*;
use crate::parser::parse::flag::{Flag, FlagKind}; use crate::parser::parse::flag::{Flag, FlagKind};
use crate::parser::parse::operator::Operator; use crate::parser::parse::operator::Operator;
use crate::parser::parse::pipeline::{Pipeline, PipelineElement}; use crate::parser::parse::pipeline::{Pipeline, PipelineElement};
use crate::parser::parse::span::{Span, Spanned};
use crate::parser::parse::token_tree::{DelimitedNode, Delimiter, PathNode, TokenNode}; use crate::parser::parse::token_tree::{DelimitedNode, Delimiter, PathNode, TokenNode};
use crate::parser::parse::tokens::{RawToken, Token}; use crate::parser::parse::tokens::{RawToken, Token};
use crate::parser::parse::unit::Unit; use crate::parser::parse::unit::Unit;
use crate::parser::CallNode; use crate::parser::CallNode;
use crate::Span;
use derive_new::new; use derive_new::new;
#[derive(new)] #[derive(new)]
@ -20,7 +20,7 @@ pub struct TokenTreeBuilder {
#[allow(unused)] #[allow(unused)]
pub type CurriedNode<T> = Box<dyn FnOnce(&mut TokenTreeBuilder) -> T + 'static>; pub type CurriedNode<T> = Box<dyn FnOnce(&mut TokenTreeBuilder) -> T + 'static>;
pub type CurriedToken = Box<dyn FnOnce(&mut TokenTreeBuilder) -> TokenNode + 'static>; pub type CurriedToken = Box<dyn FnOnce(&mut TokenTreeBuilder) -> TokenNode + 'static>;
pub type CurriedCall = Box<dyn FnOnce(&mut TokenTreeBuilder) -> Spanned<CallNode> + 'static>; pub type CurriedCall = Box<dyn FnOnce(&mut TokenTreeBuilder) -> Tagged<CallNode> + 'static>;
#[allow(unused)] #[allow(unused)]
impl TokenTreeBuilder { impl TokenTreeBuilder {
@ -92,7 +92,7 @@ impl TokenTreeBuilder {
input: (Vec<PipelineElement>, Option<Span>), input: (Vec<PipelineElement>, Option<Span>),
span: impl Into<Span>, span: impl Into<Span>,
) -> TokenNode { ) -> TokenNode {
TokenNode::Pipeline(Spanned::from_item( TokenNode::Pipeline(Tagged::from_item(
Pipeline::new(input.0, input.1.into()), Pipeline::new(input.0, input.1.into()),
span, span,
)) ))
@ -111,7 +111,7 @@ impl TokenTreeBuilder {
} }
pub fn spanned_op(input: impl Into<Operator>, span: impl Into<Span>) -> TokenNode { pub fn spanned_op(input: impl Into<Operator>, span: impl Into<Span>) -> TokenNode {
TokenNode::Operator(Spanned::from_item(input.into(), span.into())) TokenNode::Operator(Tagged::from_item(input.into(), span.into()))
} }
pub fn string(input: impl Into<String>) -> CurriedToken { pub fn string(input: impl Into<String>) -> CurriedToken {
@ -128,7 +128,7 @@ impl TokenTreeBuilder {
} }
pub fn spanned_string(input: impl Into<Span>, span: impl Into<Span>) -> TokenNode { pub fn spanned_string(input: impl Into<Span>, span: impl Into<Span>) -> TokenNode {
TokenNode::Token(Spanned::from_item( TokenNode::Token(Tagged::from_item(
RawToken::String(input.into()), RawToken::String(input.into()),
span.into(), span.into(),
)) ))
@ -146,7 +146,7 @@ impl TokenTreeBuilder {
} }
pub fn spanned_bare(input: impl Into<Span>) -> TokenNode { pub fn spanned_bare(input: impl Into<Span>) -> TokenNode {
TokenNode::Token(Spanned::from_item(RawToken::Bare, input.into())) TokenNode::Token(Tagged::from_item(RawToken::Bare, input.into()))
} }
pub fn int(input: impl Into<i64>) -> CurriedToken { pub fn int(input: impl Into<i64>) -> CurriedToken {
@ -183,7 +183,7 @@ impl TokenTreeBuilder {
) -> TokenNode { ) -> TokenNode {
let (int, unit) = (input.0.into(), input.1.into()); let (int, unit) = (input.0.into(), input.1.into());
TokenNode::Token(Spanned::from_item(RawToken::Size(int, unit), span)) TokenNode::Token(Tagged::from_item(RawToken::Size(int, unit), span))
} }
pub fn path(head: CurriedToken, tail: Vec<CurriedToken>) -> CurriedToken { pub fn path(head: CurriedToken, tail: Vec<CurriedToken>) -> CurriedToken {
@ -206,7 +206,7 @@ impl TokenTreeBuilder {
} }
pub fn spanned_path(input: (TokenNode, Vec<TokenNode>), span: impl Into<Span>) -> TokenNode { pub fn spanned_path(input: (TokenNode, Vec<TokenNode>), span: impl Into<Span>) -> TokenNode {
TokenNode::Path(Spanned::from_item( TokenNode::Path(Tagged::from_item(
PathNode::new(Box::new(input.0), input.1), PathNode::new(Box::new(input.0), input.1),
span, span,
)) ))
@ -224,7 +224,7 @@ impl TokenTreeBuilder {
} }
pub fn spanned_var(input: impl Into<Span>, span: impl Into<Span>) -> TokenNode { pub fn spanned_var(input: impl Into<Span>, span: impl Into<Span>) -> TokenNode {
TokenNode::Token(Spanned::from_item( TokenNode::Token(Tagged::from_item(
RawToken::Variable(input.into()), RawToken::Variable(input.into()),
span.into(), span.into(),
)) ))
@ -242,7 +242,7 @@ impl TokenTreeBuilder {
} }
pub fn spanned_flag(input: impl Into<Span>, span: impl Into<Span>) -> TokenNode { pub fn spanned_flag(input: impl Into<Span>, span: impl Into<Span>) -> TokenNode {
TokenNode::Flag(Spanned::from_item( TokenNode::Flag(Tagged::from_item(
Flag::new(FlagKind::Longhand, input.into()), Flag::new(FlagKind::Longhand, input.into()),
span.into(), span.into(),
)) ))
@ -260,7 +260,7 @@ impl TokenTreeBuilder {
} }
pub fn spanned_shorthand(input: impl Into<Span>, span: impl Into<Span>) -> TokenNode { pub fn spanned_shorthand(input: impl Into<Span>, span: impl Into<Span>) -> TokenNode {
TokenNode::Flag(Spanned::from_item( TokenNode::Flag(Tagged::from_item(
Flag::new(FlagKind::Shorthand, input.into()), Flag::new(FlagKind::Shorthand, input.into()),
span.into(), span.into(),
)) ))
@ -296,7 +296,7 @@ impl TokenTreeBuilder {
}) })
} }
pub fn spanned_call(input: Vec<TokenNode>, span: impl Into<Span>) -> Spanned<CallNode> { pub fn spanned_call(input: Vec<TokenNode>, span: impl Into<Span>) -> Tagged<CallNode> {
if input.len() == 0 { if input.len() == 0 {
panic!("BUG: spanned call (TODO)") panic!("BUG: spanned call (TODO)")
} }
@ -306,7 +306,7 @@ impl TokenTreeBuilder {
let head = input.next().unwrap(); let head = input.next().unwrap();
let tail = input.collect(); let tail = input.collect();
Spanned::from_item(CallNode::new(Box::new(head), tail), span) Tagged::from_item(CallNode::new(Box::new(head), tail), span)
} }
pub fn parens(input: Vec<CurriedToken>) -> CurriedToken { pub fn parens(input: Vec<CurriedToken>) -> CurriedToken {
@ -324,7 +324,7 @@ impl TokenTreeBuilder {
} }
pub fn spanned_parens(input: impl Into<Vec<TokenNode>>, span: impl Into<Span>) -> TokenNode { pub fn spanned_parens(input: impl Into<Vec<TokenNode>>, span: impl Into<Span>) -> TokenNode {
TokenNode::Delimited(Spanned::from_item( TokenNode::Delimited(Tagged::from_item(
DelimitedNode::new(Delimiter::Paren, input.into()), DelimitedNode::new(Delimiter::Paren, input.into()),
span, span,
)) ))
@ -345,7 +345,7 @@ impl TokenTreeBuilder {
} }
pub fn spanned_square(input: impl Into<Vec<TokenNode>>, span: impl Into<Span>) -> TokenNode { pub fn spanned_square(input: impl Into<Vec<TokenNode>>, span: impl Into<Span>) -> TokenNode {
TokenNode::Delimited(Spanned::from_item( TokenNode::Delimited(Tagged::from_item(
DelimitedNode::new(Delimiter::Square, input.into()), DelimitedNode::new(Delimiter::Square, input.into()),
span, span,
)) ))
@ -366,7 +366,7 @@ impl TokenTreeBuilder {
} }
pub fn spanned_brace(input: impl Into<Vec<TokenNode>>, span: impl Into<Span>) -> TokenNode { pub fn spanned_brace(input: impl Into<Vec<TokenNode>>, span: impl Into<Span>) -> TokenNode {
TokenNode::Delimited(Spanned::from_item( TokenNode::Delimited(Tagged::from_item(
DelimitedNode::new(Delimiter::Brace, input.into()), DelimitedNode::new(Delimiter::Brace, input.into()),
span, span,
)) ))

View file

@ -1,6 +1,5 @@
use crate::parser::parse::span::*;
use crate::parser::parse::unit::*; use crate::parser::parse::unit::*;
use crate::Text; use crate::{Span, Tagged, Text};
use std::fmt; use std::fmt;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
@ -24,7 +23,7 @@ impl RawToken {
} }
} }
pub type Token = Spanned<RawToken>; pub type Token = Tagged<RawToken>;
impl Token { impl Token {
pub fn debug(&self, source: &'a Text) -> DebugToken<'a> { pub fn debug(&self, source: &'a Text) -> DebugToken<'a> {

View file

@ -1,20 +1,20 @@
use crate::errors::{ArgumentError, ShellError}; use crate::errors::{ArgumentError, ShellError};
use crate::parser::registry::{CommandConfig, CommandRegistry, NamedType, PositionalType}; use crate::parser::registry::{CommandConfig, CommandRegistry, NamedType, PositionalType};
use crate::parser::{baseline_parse_tokens, CallNode, Span, Spanned}; use crate::parser::{baseline_parse_tokens, CallNode};
use crate::parser::{ use crate::parser::{
hir::{self, NamedArguments}, hir::{self, NamedArguments},
Flag, RawToken, TokenNode, Flag, RawToken, TokenNode,
}; };
use crate::Text; use crate::{Span, Tag, Tagged, Text};
use log::trace; use log::trace;
pub fn parse_command( pub fn parse_command(
config: &CommandConfig, config: &CommandConfig,
registry: &dyn CommandRegistry, registry: &dyn CommandRegistry,
call: &Spanned<CallNode>, call: &Tagged<CallNode>,
source: &Text, source: &Text,
) -> Result<hir::Call, ShellError> { ) -> Result<hir::Call, ShellError> {
let Spanned { item: raw_call, .. } = call; let Tagged { item: raw_call, .. } = call;
trace!("Processing {:?}", config); trace!("Processing {:?}", config);
@ -31,7 +31,7 @@ pub fn parse_command(
.collect() .collect()
}); });
match parse_command_tail(&config, registry, children, source, call.span)? { match parse_command_tail(&config, registry, children, source, call.span())? {
None => Ok(hir::Call::new(Box::new(head), None, None)), None => Ok(hir::Call::new(Box::new(head), None, None)),
Some((positional, named)) => Ok(hir::Call::new(Box::new(head), positional, named)), Some((positional, named)) => Ok(hir::Call::new(Box::new(head), positional, named)),
} }
@ -40,16 +40,16 @@ pub fn parse_command(
fn parse_command_head(head: &TokenNode) -> Result<hir::Expression, ShellError> { fn parse_command_head(head: &TokenNode) -> Result<hir::Expression, ShellError> {
match head { match head {
TokenNode::Token( TokenNode::Token(
spanned @ Spanned { spanned @ Tagged {
item: RawToken::Bare, item: RawToken::Bare,
.. ..
}, },
) => Ok(spanned.map(|_| hir::RawExpression::Literal(hir::Literal::Bare))), ) => Ok(spanned.map(|_| hir::RawExpression::Literal(hir::Literal::Bare))),
TokenNode::Token(Spanned { TokenNode::Token(Tagged {
item: RawToken::String(inner_span), item: RawToken::String(inner_span),
span, tag: Tag { span },
}) => Ok(Spanned::from_item( }) => Ok(Tagged::from_item(
hir::RawExpression::Literal(hir::Literal::String(*inner_span)), hir::RawExpression::Literal(hir::Literal::String(*inner_span)),
*span, *span,
)), )),
@ -96,7 +96,7 @@ fn parse_command_tail(
return Err(ShellError::argument_error( return Err(ShellError::argument_error(
config.name.clone(), config.name.clone(),
ArgumentError::MissingValueForName(name.to_string()), ArgumentError::MissingValueForName(name.to_string()),
flag.span, flag.span(),
)); ));
} }
@ -117,7 +117,7 @@ fn parse_command_tail(
return Err(ShellError::argument_error( return Err(ShellError::argument_error(
config.name().clone(), config.name().clone(),
ArgumentError::MissingValueForName(name.to_string()), ArgumentError::MissingValueForName(name.to_string()),
flag.span, flag.span(),
)); ));
} }
@ -202,7 +202,7 @@ fn extract_mandatory(
tokens: &mut hir::TokensIterator<'a>, tokens: &mut hir::TokensIterator<'a>,
source: &Text, source: &Text,
span: Span, span: Span,
) -> Result<(usize, Spanned<Flag>), ShellError> { ) -> Result<(usize, Tagged<Flag>), ShellError> {
let flag = tokens.extract(|t| t.as_flag(name, source)); let flag = tokens.extract(|t| t.as_flag(name, source));
match flag { match flag {
@ -223,7 +223,7 @@ fn extract_optional(
name: &str, name: &str,
tokens: &mut hir::TokensIterator<'a>, tokens: &mut hir::TokensIterator<'a>,
source: &Text, source: &Text,
) -> Result<(Option<(usize, Spanned<Flag>)>), ShellError> { ) -> Result<(Option<(usize, Tagged<Flag>)>), ShellError> {
let flag = tokens.extract(|t| t.as_flag(name, source)); let flag = tokens.extract(|t| t.as_flag(name, source));
match flag { match flag {

View file

@ -1,5 +1,5 @@
use crate::evaluate::{evaluate_baseline_expr, Scope}; use crate::evaluate::{evaluate_baseline_expr, Scope};
use crate::parser::{hir, hir::SyntaxType, parse_command, CallNode, Spanned}; use crate::parser::{hir, hir::SyntaxType, parse_command, CallNode};
use crate::prelude::*; use crate::prelude::*;
use derive_new::new; use derive_new::new;
use getset::Getters; use getset::Getters;
@ -81,13 +81,13 @@ pub struct CommandConfig {
#[derive(Debug, Default, new, Serialize, Deserialize, Clone)] #[derive(Debug, Default, new, Serialize, Deserialize, Clone)]
pub struct Args { pub struct Args {
pub positional: Option<Vec<Spanned<Value>>>, pub positional: Option<Vec<Tagged<Value>>>,
pub named: Option<IndexMap<String, Spanned<Value>>>, pub named: Option<IndexMap<String, Tagged<Value>>>,
} }
#[derive(new)] #[derive(new)]
pub struct DebugPositional<'a> { pub struct DebugPositional<'a> {
positional: &'a Option<Vec<Spanned<Value>>>, positional: &'a Option<Vec<Tagged<Value>>>,
} }
impl fmt::Debug for DebugPositional<'a> { impl fmt::Debug for DebugPositional<'a> {
@ -104,7 +104,7 @@ impl fmt::Debug for DebugPositional<'a> {
#[derive(new)] #[derive(new)]
pub struct DebugNamed<'a> { pub struct DebugNamed<'a> {
named: &'a Option<IndexMap<String, Spanned<Value>>>, named: &'a Option<IndexMap<String, Tagged<Value>>>,
} }
impl fmt::Debug for DebugNamed<'a> { impl fmt::Debug for DebugNamed<'a> {
@ -139,14 +139,14 @@ impl Args {
DebugArgs { args: self } DebugArgs { args: self }
} }
pub fn nth(&self, pos: usize) -> Option<&Spanned<Value>> { pub fn nth(&self, pos: usize) -> Option<&Tagged<Value>> {
match &self.positional { match &self.positional {
None => None, None => None,
Some(array) => array.iter().nth(pos), Some(array) => array.iter().nth(pos),
} }
} }
pub fn expect_nth(&self, pos: usize) -> Result<&Spanned<Value>, ShellError> { pub fn expect_nth(&self, pos: usize) -> Result<&Tagged<Value>, ShellError> {
match &self.positional { match &self.positional {
None => Err(ShellError::unimplemented("Better error: expect_nth")), None => Err(ShellError::unimplemented("Better error: expect_nth")),
Some(array) => match array.iter().nth(pos) { Some(array) => match array.iter().nth(pos) {
@ -170,7 +170,7 @@ impl Args {
} }
} }
pub fn get(&self, name: &str) -> Option<&Spanned<Value>> { pub fn get(&self, name: &str) -> Option<&Tagged<Value>> {
match &self.named { match &self.named {
None => None, None => None,
Some(named) => named.get(name), Some(named) => named.get(name),
@ -190,11 +190,11 @@ impl Args {
pub enum PositionalIter<'a> { pub enum PositionalIter<'a> {
Empty, Empty,
Array(std::slice::Iter<'a, Spanned<Value>>), Array(std::slice::Iter<'a, Tagged<Value>>),
} }
impl Iterator for PositionalIter<'a> { impl Iterator for PositionalIter<'a> {
type Item = &'a Spanned<Value>; type Item = &'a Tagged<Value>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
match self { match self {
@ -207,7 +207,7 @@ impl Iterator for PositionalIter<'a> {
impl CommandConfig { impl CommandConfig {
crate fn evaluate_args( crate fn evaluate_args(
&self, &self,
call: &Spanned<CallNode>, call: &Tagged<CallNode>,
registry: &dyn CommandRegistry, registry: &dyn CommandRegistry,
scope: &Scope, scope: &Scope,
source: &Text, source: &Text,
@ -217,80 +217,6 @@ impl CommandConfig {
trace!("parsed args: {:?}", args); trace!("parsed args: {:?}", args);
evaluate_args(args, registry, scope, source) evaluate_args(args, registry, scope, source)
// let mut positional: Vec<Spanned<Value>> = vec![];
// let mut named: IndexMap<String, Value> = IndexMap::default();
// let mut args: Vec<TokenNode> = args.cloned().collect();
// for (key, ty) in self.named.iter() {
// let index = args.iter().position(|a| a.is_flag(&key, source));
// match (index, ty) {
// (Some(i), NamedType::Switch) => {
// args.remove(i);
// named.insert(key.clone(), Value::boolean(true));
// }
// (None, NamedType::Switch) => {}
// (Some(i), NamedType::Optional(v)) => {
// args.remove(i);
// named.insert(key.clone(), extract_named(&mut args, i, v)?);
// }
// (None, NamedType::Optional(_)) => {}
// (Some(i), NamedType::Mandatory(v)) => {
// args.remove(i);
// named.insert(key.clone(), extract_named(&mut args, i, v)?);
// }
// (None, NamedType::Mandatory(_)) => {
// return Err(ShellError::string(&format!(
// "Expected mandatory argument {}, but it was missing",
// key
// )))
// }
// }
// }
// let mut args = args.into_iter();
// for param in &self.mandatory_positional {
// let arg = args.next();
// let value = match arg {
// None => {
// return Err(ShellError::string(format!(
// "expected mandatory positional argument {}",
// param.name()
// )))
// }
// Some(arg) => param.evaluate(arg.clone(), scope, source)?,
// };
// positional.push(value);
// }
// if self.rest_positional {
// let rest: Result<Vec<Spanned<Value>>, _> = args
// .map(|i| evaluate_baseline_expr(&i, &Scope::empty(), source))
// .collect();
// positional.extend(rest?);
// } else {
// let rest: Vec<TokenNode> = args.collect();
// if rest.len() > 0 {
// return Err(ShellError::string(&format!(
// "Too many arguments, extras: {:?}",
// rest
// )));
// }
// }
// Ok(Args { positional, named })
} }
#[allow(unused)] #[allow(unused)]
@ -317,7 +243,7 @@ fn evaluate_args(
let positional = positional?; let positional = positional?;
let named: Result<Option<IndexMap<String, Spanned<Value>>>, ShellError> = args let named: Result<Option<IndexMap<String, Tagged<Value>>>, ShellError> = args
.named() .named()
.as_ref() .as_ref()
.map(|n| { .map(|n| {
@ -326,10 +252,8 @@ fn evaluate_args(
for (name, value) in n.named.iter() { for (name, value) in n.named.iter() {
match value { match value {
hir::named::NamedValue::PresentSwitch(span) => { hir::named::NamedValue::PresentSwitch(span) => {
results.insert( results
name.clone(), .insert(name.clone(), Tagged::from_item(Value::boolean(true), *span));
Spanned::from_item(Value::boolean(true), *span),
);
} }
hir::named::NamedValue::Value(expr) => { hir::named::NamedValue::Value(expr) => {
results.insert( results.insert(

View file

@ -1,4 +1,5 @@
use crate::{CallInfo, CommandConfig, ReturnValue, ShellError, Spanned, Value}; use crate::Tagged;
use crate::{CallInfo, CommandConfig, ReturnValue, ShellError, Value};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::io; use std::io;
@ -10,7 +11,7 @@ pub trait Plugin {
Ok(vec![]) Ok(vec![])
} }
#[allow(unused)] #[allow(unused)]
fn filter(&mut self, input: Spanned<Value>) -> Result<Vec<ReturnValue>, ShellError> { fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![]) Ok(vec![])
} }
#[allow(unused)] #[allow(unused)]
@ -18,7 +19,7 @@ pub trait Plugin {
Ok(vec![]) Ok(vec![])
} }
#[allow(unused)] #[allow(unused)]
fn sink(&mut self, call_info: CallInfo, input: Vec<Spanned<Value>>) {} fn sink(&mut self, call_info: CallInfo, input: Vec<Tagged<Value>>) {}
fn quit(&mut self) {} fn quit(&mut self) {}
} }
@ -138,11 +139,11 @@ pub enum NuCommand {
params: CallInfo, params: CallInfo,
}, },
filter { filter {
params: Spanned<Value>, params: Tagged<Value>,
}, },
end_filter, end_filter,
sink { sink {
params: (CallInfo, Vec<Spanned<Value>>), params: (CallInfo, Vec<Tagged<Value>>),
}, },
quit, quit,
} }

View file

@ -1,7 +1,7 @@
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, Plugin, PositionalType, Primitive, ReturnSuccess, serve_plugin, CallInfo, CommandConfig, Plugin, PositionalType, Primitive, ReturnSuccess,
ReturnValue, ShellError, Spanned, Value, ReturnValue, ShellError, Tagged, Value,
}; };
struct Add { struct Add {
@ -16,10 +16,11 @@ impl Add {
} }
} }
fn add(&self, value: Spanned<Value>) -> Result<Spanned<Value>, ShellError> { fn add(&self, value: Tagged<Value>) -> Result<Tagged<Value>, ShellError> {
let value_span = value.span();
match (value.item, self.value.clone()) { match (value.item, self.value.clone()) {
(obj @ Value::Object(_), Some(v)) => match &self.field { (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_span, &f, v) {
Some(v) => return Ok(v), Some(v) => return Ok(v),
None => { None => {
return Err(ShellError::string( return Err(ShellError::string(
@ -56,7 +57,7 @@ impl Plugin for Add {
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> { fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
if let Some(args) = call_info.args.positional { if let Some(args) = call_info.args.positional {
match &args[0] { match &args[0] {
Spanned { Tagged {
item: Value::Primitive(Primitive::String(s)), item: Value::Primitive(Primitive::String(s)),
.. ..
} => { } => {
@ -70,7 +71,7 @@ impl Plugin for Add {
} }
} }
match &args[1] { match &args[1] {
Spanned { item: v, .. } => { Tagged { item: v, .. } => {
self.value = Some(v.clone()); self.value = Some(v.clone());
} }
} }
@ -79,7 +80,7 @@ impl Plugin for Add {
Ok(vec![]) Ok(vec![])
} }
fn filter(&mut self, input: Spanned<Value>) -> Result<Vec<ReturnValue>, ShellError> { fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![ReturnSuccess::value(self.add(input)?)]) Ok(vec![ReturnSuccess::value(self.add(input)?)])
} }
} }

View file

@ -2,8 +2,7 @@
use crossterm::{cursor, terminal, Attribute, RawScreen}; use crossterm::{cursor, terminal, Attribute, RawScreen};
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, NamedType, Plugin, ShellError, SpanSource, Spanned, serve_plugin, CallInfo, CommandConfig, NamedType, Plugin, ShellError, SpanSource, Tagged, Value,
Value,
}; };
use pretty_hex::*; use pretty_hex::*;
@ -29,14 +28,15 @@ impl Plugin for BinaryView {
}) })
} }
fn sink(&mut self, call_info: CallInfo, input: Vec<Spanned<Value>>) { fn sink(&mut self, call_info: CallInfo, input: Vec<Tagged<Value>>) {
for v in input { for v in input {
match v { let value_span = v.span();
Spanned { match v.item {
item: Value::Binary(b), Value::Binary(b) => {
span, let source = value_span
} => { .source
let source = span.source.map(|x| call_info.source_map.get(&x)).flatten(); .map(|x| call_info.source_map.get(&x))
.flatten();
let _ = view_binary(&b, source, call_info.args.has("lores")); let _ = view_binary(&b, source, call_info.args.has("lores"));
} }
_ => {} _ => {}

View file

@ -1,7 +1,7 @@
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, Plugin, PositionalType, Primitive, ReturnSuccess, serve_plugin, CallInfo, CommandConfig, Plugin, PositionalType, Primitive, ReturnSuccess,
ReturnValue, ShellError, Spanned, Value, ReturnValue, ShellError, Tagged, Value,
}; };
struct Edit { struct Edit {
@ -16,10 +16,11 @@ impl Edit {
} }
} }
fn edit(&self, value: Spanned<Value>) -> Result<Spanned<Value>, ShellError> { fn edit(&self, value: Tagged<Value>) -> Result<Tagged<Value>, ShellError> {
let value_span = value.span();
match (value.item, self.value.clone()) { match (value.item, self.value.clone()) {
(obj @ Value::Object(_), Some(v)) => match &self.field { (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_span, &f, v) {
Some(v) => return Ok(v), Some(v) => return Ok(v),
None => { None => {
return Err(ShellError::string( return Err(ShellError::string(
@ -56,7 +57,7 @@ impl Plugin for Edit {
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> { fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
if let Some(args) = call_info.args.positional { if let Some(args) = call_info.args.positional {
match &args[0] { match &args[0] {
Spanned { Tagged {
item: Value::Primitive(Primitive::String(s)), item: Value::Primitive(Primitive::String(s)),
.. ..
} => { } => {
@ -70,7 +71,7 @@ impl Plugin for Edit {
} }
} }
match &args[1] { match &args[1] {
Spanned { item: v, .. } => { Tagged { item: v, .. } => {
self.value = Some(v.clone()); self.value = Some(v.clone());
} }
} }
@ -79,7 +80,7 @@ impl Plugin for Edit {
Ok(vec![]) Ok(vec![])
} }
fn filter(&mut self, input: Spanned<Value>) -> Result<Vec<ReturnValue>, ShellError> { fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![ReturnSuccess::value(self.edit(input)?)]) Ok(vec![ReturnSuccess::value(self.edit(input)?)])
} }
} }

View file

@ -1,7 +1,7 @@
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, NamedType, Plugin, PositionalType, Primitive, serve_plugin, CallInfo, CommandConfig, NamedType, Plugin, PositionalType, Primitive,
ReturnSuccess, ReturnValue, ShellError, Spanned, SpannedItem, Value, ReturnSuccess, ReturnValue, ShellError, Tagged, TaggedItem, Value,
}; };
struct Inc { struct Inc {
@ -22,20 +22,20 @@ impl Inc {
fn inc( fn inc(
&self, &self,
value: Spanned<Value>, value: Tagged<Value>,
field: &Option<String>, field: &Option<String>,
) -> Result<Spanned<Value>, ShellError> { ) -> Result<Tagged<Value>, ShellError> {
match value.item { match value.item {
Value::Primitive(Primitive::Int(i)) => Ok(Value::int(i + 1).spanned(value.span)), Value::Primitive(Primitive::Int(i)) => Ok(Value::int(i + 1).tagged(value.span())),
Value::Primitive(Primitive::Bytes(b)) => { Value::Primitive(Primitive::Bytes(b)) => {
Ok(Value::bytes(b + 1 as u64).spanned(value.span)) Ok(Value::bytes(b + 1 as u64).tagged(value.span()))
} }
Value::Primitive(Primitive::String(s)) => { Value::Primitive(Primitive::String(ref s)) => {
if let Ok(i) = s.parse::<u64>() { if let Ok(i) = s.parse::<u64>() {
Ok(Spanned { Ok(Tagged::from_item(
item: Value::string(format!("{}", i + 1)), Value::string(format!("{}", i + 1)),
span: value.span, value.span(),
}) ))
} else if let Ok(mut ver) = semver::Version::parse(&s) { } else if let Ok(mut ver) = semver::Version::parse(&s) {
if self.major { if self.major {
ver.increment_major(); ver.increment_major();
@ -45,17 +45,17 @@ impl Inc {
self.patch; self.patch;
ver.increment_patch(); ver.increment_patch();
} }
Ok(Spanned { Ok(Tagged::from_item(
item: Value::string(ver.to_string()), Value::string(ver.to_string()),
span: value.span, value.span(),
}) ))
} else { } else {
Err(ShellError::string("string could not be incremented")) Err(ShellError::string("string could not be incremented"))
} }
} }
Value::Object(_) => match field { Value::Object(_) => match field {
Some(f) => { Some(f) => {
let replacement = match value.item.get_data_by_path(value.span, f) { let replacement = match value.item.get_data_by_path(value.span(), f) {
Some(result) => self.inc(result.map(|x| x.clone()), &None)?, Some(result) => self.inc(result.map(|x| x.clone()), &None)?,
None => { None => {
return Err(ShellError::string("inc could not find field to replace")) return Err(ShellError::string("inc could not find field to replace"))
@ -63,7 +63,7 @@ impl Inc {
}; };
match value match value
.item .item
.replace_data_at_path(value.span, f, replacement.item.clone()) .replace_data_at_path(value.span(), f, replacement.item.clone())
{ {
Some(v) => return Ok(v), Some(v) => return Ok(v),
None => { None => {
@ -113,7 +113,7 @@ impl Plugin for Inc {
if let Some(args) = call_info.args.positional { if let Some(args) = call_info.args.positional {
for arg in args { for arg in args {
match arg { match arg {
Spanned { Tagged {
item: Value::Primitive(Primitive::String(s)), item: Value::Primitive(Primitive::String(s)),
.. ..
} => { } => {
@ -132,7 +132,7 @@ impl Plugin for Inc {
Ok(vec![]) Ok(vec![])
} }
fn filter(&mut self, input: Spanned<Value>) -> Result<Vec<ReturnValue>, ShellError> { fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![ReturnSuccess::value(self.inc(input, &self.field)?)]) Ok(vec![ReturnSuccess::value(self.inc(input, &self.field)?)])
} }
} }

View file

@ -1,7 +1,7 @@
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, Plugin, Primitive, ReturnSuccess, ReturnValue, serve_plugin, CallInfo, CommandConfig, Plugin, Primitive, ReturnSuccess, ReturnValue,
ShellError, Spanned, Value, ShellError, Tagged, Value,
}; };
struct Skip { struct Skip {
@ -28,7 +28,7 @@ impl Plugin for Skip {
if let Some(args) = call_info.args.positional { if let Some(args) = call_info.args.positional {
for arg in args { for arg in args {
match arg { match arg {
Spanned { Tagged {
item: Value::Primitive(Primitive::Int(i)), item: Value::Primitive(Primitive::Int(i)),
.. ..
} => { } => {
@ -38,7 +38,7 @@ impl Plugin for Skip {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"Unrecognized type in params", "Unrecognized type in params",
"expected an integer", "expected an integer",
arg.span, arg.span(),
)) ))
} }
} }
@ -48,7 +48,7 @@ impl Plugin for Skip {
Ok(vec![]) Ok(vec![])
} }
fn filter(&mut self, input: Spanned<Value>) -> Result<Vec<ReturnValue>, ShellError> { fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
if self.skip_amount == 0 { if self.skip_amount == 0 {
Ok(vec![ReturnSuccess::value(input)]) Ok(vec![ReturnSuccess::value(input)])
} else { } else {

View file

@ -1,7 +1,7 @@
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, NamedType, Plugin, PositionalType, Primitive, serve_plugin, CallInfo, CommandConfig, NamedType, Plugin, PositionalType, Primitive,
ReturnSuccess, ReturnValue, ShellError, Spanned, Value, ReturnSuccess, ReturnValue, ShellError, Tagged, Value,
}; };
struct Str { struct Str {
@ -69,17 +69,17 @@ impl Str {
impl Str { impl Str {
fn strutils( fn strutils(
&self, &self,
value: Spanned<Value>, value: Tagged<Value>,
field: &Option<String>, field: &Option<String>,
) -> Result<Spanned<Value>, ShellError> { ) -> Result<Tagged<Value>, ShellError> {
match value.item { match value.item {
Value::Primitive(Primitive::String(s)) => Ok(Spanned { Value::Primitive(Primitive::String(ref s)) => Ok(Tagged::from_item(
item: Value::string(self.apply(&s)), Value::string(self.apply(&s)),
span: value.span, value.span(),
}), )),
Value::Object(_) => match field { Value::Object(_) => match field {
Some(f) => { Some(f) => {
let replacement = match value.item.get_data_by_path(value.span, f) { let replacement = match value.item.get_data_by_path(value.span(), f) {
Some(result) => self.strutils(result.map(|x| x.clone()), &None)?, Some(result) => self.strutils(result.map(|x| x.clone()), &None)?,
None => { None => {
return Err(ShellError::string("str could not find field to replace")) return Err(ShellError::string("str could not find field to replace"))
@ -87,7 +87,7 @@ impl Str {
}; };
match value match value
.item .item
.replace_data_at_path(value.span, f, replacement.item.clone()) .replace_data_at_path(value.span(), f, replacement.item.clone())
{ {
Some(v) => return Ok(v), Some(v) => return Ok(v),
None => { None => {
@ -135,7 +135,7 @@ impl Plugin for Str {
if let Some(args) = call_info.args.positional { if let Some(args) = call_info.args.positional {
for arg in args { for arg in args {
match arg { match arg {
Spanned { Tagged {
item: Value::Primitive(Primitive::String(s)), item: Value::Primitive(Primitive::String(s)),
.. ..
} => { } => {
@ -161,7 +161,7 @@ impl Plugin for Str {
Ok(vec![]) Ok(vec![])
} }
fn filter(&mut self, input: Spanned<Value>) -> Result<Vec<ReturnValue>, ShellError> { fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![ReturnSuccess::value( Ok(vec![ReturnSuccess::value(
self.strutils(input, &self.field)?, self.strutils(input, &self.field)?,
)]) )])

View file

@ -1,30 +1,27 @@
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, Plugin, Primitive, ReturnSuccess, ReturnValue, serve_plugin, CallInfo, CommandConfig, Plugin, Primitive, ReturnSuccess, ReturnValue,
ShellError, Spanned, Value, ShellError, Tag, Tagged, Value,
}; };
struct Sum { struct Sum {
total: Option<Spanned<Value>>, total: Option<Tagged<Value>>,
} }
impl Sum { impl Sum {
fn new() -> Sum { fn new() -> Sum {
Sum { total: None } Sum { total: None }
} }
fn sum(&mut self, value: Spanned<Value>) -> Result<(), ShellError> { fn sum(&mut self, value: Tagged<Value>) -> Result<(), ShellError> {
match value.item { match value.item {
Value::Primitive(Primitive::Int(i)) => { Value::Primitive(Primitive::Int(i)) => {
match self.total { match self.total {
Some(Spanned { Some(Tagged {
item: Value::Primitive(Primitive::Int(j)), item: Value::Primitive(Primitive::Int(j)),
span, tag: Tag { span },
}) => { }) => {
//TODO: handle overflow //TODO: handle overflow
self.total = Some(Spanned { self.total = Some(Tagged::from_item(Value::int(i + j), span));
item: Value::int(i + j),
span,
});
Ok(()) Ok(())
} }
None => { None => {
@ -38,15 +35,12 @@ impl Sum {
} }
Value::Primitive(Primitive::Bytes(b)) => { Value::Primitive(Primitive::Bytes(b)) => {
match self.total { match self.total {
Some(Spanned { Some(Tagged {
item: Value::Primitive(Primitive::Bytes(j)), item: Value::Primitive(Primitive::Bytes(j)),
span, tag: Tag { span },
}) => { }) => {
//TODO: handle overflow //TODO: handle overflow
self.total = Some(Spanned { self.total = Some(Tagged::from_item(Value::bytes(b + j), span));
item: Value::bytes(b + j),
span,
});
Ok(()) Ok(())
} }
None => { None => {
@ -81,7 +75,7 @@ impl Plugin for Sum {
Ok(vec![]) Ok(vec![])
} }
fn filter(&mut self, input: Spanned<Value>) -> Result<Vec<ReturnValue>, ShellError> { fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
self.sum(input)?; self.sum(input)?;
Ok(vec![]) Ok(vec![])
} }

View file

@ -6,7 +6,7 @@ use heim::{disk, memory};
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, Plugin, Primitive, ReturnSuccess, ReturnValue, serve_plugin, CallInfo, CommandConfig, Plugin, Primitive, ReturnSuccess, ReturnValue,
ShellError, Span, Spanned, SpannedDictBuilder, Value, OF64, ShellError, Span, Tagged, TaggedDictBuilder, Value, OF64,
}; };
use std::ffi::OsStr; use std::ffi::OsStr;
@ -19,19 +19,19 @@ impl Sys {
//TODO: add more error checking //TODO: add more error checking
async fn cpu(span: Span) -> Option<Spanned<Value>> { async fn cpu(span: Span) -> Option<Tagged<Value>> {
if let (Ok(num_cpu), Ok(cpu_speed)) = (sys_info::cpu_num(), sys_info::cpu_speed()) { if let (Ok(num_cpu), Ok(cpu_speed)) = (sys_info::cpu_num(), sys_info::cpu_speed()) {
let mut cpu_idx = SpannedDictBuilder::new(span); let mut cpu_idx = TaggedDictBuilder::new(span);
cpu_idx.insert("cores", Primitive::Int(num_cpu as i64)); cpu_idx.insert("cores", Primitive::Int(num_cpu as i64));
cpu_idx.insert("speed", Primitive::Int(cpu_speed as i64)); cpu_idx.insert("speed", Primitive::Int(cpu_speed as i64));
Some(cpu_idx.into_spanned_value()) Some(cpu_idx.into_tagged_value())
} else { } else {
None None
} }
} }
async fn mem(span: Span) -> Spanned<Value> { async fn mem(span: Span) -> Tagged<Value> {
let mut dict = SpannedDictBuilder::new(span); let mut dict = TaggedDictBuilder::new(span);
if let Ok(memory) = memory::memory().await { if let Ok(memory) = memory::memory().await {
dict.insert("total", Value::bytes(memory.total().get())); dict.insert("total", Value::bytes(memory.total().get()));
@ -42,11 +42,11 @@ async fn mem(span: Span) -> Spanned<Value> {
dict.insert("swap free", Value::bytes(swap.free().get())); dict.insert("swap free", Value::bytes(swap.free().get()));
} }
dict.into_spanned_value() dict.into_tagged_value()
} }
async fn host(span: Span) -> Spanned<Value> { async fn host(span: Span) -> Tagged<Value> {
let mut dict = SpannedDictBuilder::new(span); let mut dict = TaggedDictBuilder::new(span);
// OS // OS
if let Ok(platform) = heim::host::platform().await { if let Ok(platform) = heim::host::platform().await {
@ -58,7 +58,7 @@ async fn host(span: Span) -> Spanned<Value> {
// Uptime // Uptime
if let Ok(uptime) = heim::host::uptime().await { if let Ok(uptime) = heim::host::uptime().await {
let mut uptime_dict = SpannedDictBuilder::new(span); let mut uptime_dict = TaggedDictBuilder::new(span);
let uptime = uptime.get().round() as i64; let uptime = uptime.get().round() as i64;
let days = uptime / (60 * 60 * 24); let days = uptime / (60 * 60 * 24);
@ -71,7 +71,7 @@ async fn host(span: Span) -> Spanned<Value> {
uptime_dict.insert("mins", Value::int(minutes)); uptime_dict.insert("mins", Value::int(minutes));
uptime_dict.insert("secs", Value::int(seconds)); uptime_dict.insert("secs", Value::int(seconds));
dict.insert_spanned("uptime", uptime_dict.into_spanned_value()); dict.insert_tagged("uptime", uptime_dict.into_tagged_value());
} }
// Users // Users
@ -79,16 +79,13 @@ async fn host(span: Span) -> Spanned<Value> {
let mut user_vec = vec![]; let mut user_vec = vec![];
while let Some(user) = users.next().await { while let Some(user) = users.next().await {
if let Ok(user) = user { if let Ok(user) = user {
user_vec.push(Spanned { user_vec.push(Tagged::from_item(Value::string(user.username()), span));
item: Value::string(user.username()),
span,
});
} }
} }
let user_list = Value::List(user_vec); let user_list = Value::List(user_vec);
dict.insert("users", user_list); dict.insert("users", user_list);
dict.into_spanned_value() dict.into_tagged_value()
} }
async fn disks(span: Span) -> Value { async fn disks(span: Span) -> Value {
@ -96,7 +93,7 @@ async fn disks(span: Span) -> Value {
let mut partitions = disk::partitions_physical(); let mut partitions = disk::partitions_physical();
while let Some(part) = partitions.next().await { while let Some(part) = partitions.next().await {
if let Ok(part) = part { if let Ok(part) = part {
let mut dict = SpannedDictBuilder::new(span); let mut dict = TaggedDictBuilder::new(span);
dict.insert( dict.insert(
"device", "device",
Value::string( Value::string(
@ -113,7 +110,7 @@ async fn disks(span: Span) -> Value {
dict.insert("used", Value::bytes(usage.used().get())); dict.insert("used", Value::bytes(usage.used().get()));
dict.insert("free", Value::bytes(usage.free().get())); dict.insert("free", Value::bytes(usage.free().get()));
} }
output.push(dict.into_spanned_value()); output.push(dict.into_tagged_value());
} }
} }
@ -125,9 +122,9 @@ async fn temp(span: Span) -> Value {
let system = sysinfo::System::new_with_specifics(RefreshKind::new().with_system()); let system = sysinfo::System::new_with_specifics(RefreshKind::new().with_system());
let components_list = system.get_components_list(); let components_list = system.get_components_list();
if components_list.len() > 0 { if components_list.len() > 0 {
let mut v: Vec<Spanned<Value>> = vec![]; let mut v: Vec<Tagged<Value>> = vec![];
for component in components_list { for component in components_list {
let mut component_idx = SpannedDictBuilder::new(span); let mut component_idx = TaggedDictBuilder::new(span);
component_idx.insert("name", Primitive::String(component.get_label().to_string())); component_idx.insert("name", Primitive::String(component.get_label().to_string()));
component_idx.insert( component_idx.insert(
"temp", "temp",
@ -148,7 +145,7 @@ async fn temp(span: Span) -> Value {
} }
} }
async fn net(span: Span) -> Spanned<Value> { async fn net(span: Span) -> Tagged<Value> {
use sysinfo::{NetworkExt, RefreshKind, SystemExt}; use sysinfo::{NetworkExt, RefreshKind, SystemExt};
let system = sysinfo::System::new_with_specifics(RefreshKind::new().with_network()); let system = sysinfo::System::new_with_specifics(RefreshKind::new().with_network());
@ -156,25 +153,25 @@ async fn net(span: Span) -> Spanned<Value> {
let incoming = network.get_income(); let incoming = network.get_income();
let outgoing = network.get_outcome(); let outgoing = network.get_outcome();
let mut network_idx = SpannedDictBuilder::new(span); let mut network_idx = TaggedDictBuilder::new(span);
network_idx.insert("incoming", Value::bytes(incoming)); network_idx.insert("incoming", Value::bytes(incoming));
network_idx.insert("outgoing", Value::bytes(outgoing)); network_idx.insert("outgoing", Value::bytes(outgoing));
network_idx.into_spanned_value() network_idx.into_tagged_value()
} }
async fn sysinfo(span: Span) -> Vec<Spanned<Value>> { async fn sysinfo(span: Span) -> Vec<Tagged<Value>> {
let mut sysinfo = SpannedDictBuilder::new(span); let mut sysinfo = TaggedDictBuilder::new(span);
sysinfo.insert_spanned("host", host(span).await); sysinfo.insert_tagged("host", host(span).await);
if let Some(cpu) = cpu(span).await { if let Some(cpu) = cpu(span).await {
sysinfo.insert_spanned("cpu", cpu); sysinfo.insert_tagged("cpu", cpu);
} }
sysinfo.insert("disks", disks(span).await); sysinfo.insert("disks", disks(span).await);
sysinfo.insert_spanned("mem", mem(span).await); sysinfo.insert_tagged("mem", mem(span).await);
sysinfo.insert("temp", temp(span).await); sysinfo.insert("temp", temp(span).await);
sysinfo.insert_spanned("net", net(span).await); sysinfo.insert_tagged("net", net(span).await);
vec![sysinfo.into_spanned_value()] vec![sysinfo.into_tagged_value()]
} }
impl Plugin for Sys { impl Plugin for Sys {
@ -197,7 +194,7 @@ impl Plugin for Sys {
.collect()) .collect())
} }
fn filter(&mut self, _: Spanned<Value>) -> Result<Vec<ReturnValue>, ShellError> { fn filter(&mut self, _: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![]) Ok(vec![])
} }
} }

View file

@ -4,7 +4,7 @@ use crossterm::{cursor, terminal, RawScreen};
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, Plugin, Primitive, ShellError, SourceMap, SpanSource, serve_plugin, CallInfo, CommandConfig, Plugin, Primitive, ShellError, SourceMap, SpanSource,
Spanned, Value, Tagged, Value,
}; };
use rawkey::RawKey; use rawkey::RawKey;
@ -40,7 +40,7 @@ impl Plugin for TextView {
}) })
} }
fn sink(&mut self, call_info: CallInfo, input: Vec<Spanned<Value>>) { fn sink(&mut self, call_info: CallInfo, input: Vec<Tagged<Value>>) {
view_text_value(&input[0], &call_info.source_map); view_text_value(&input[0], &call_info.source_map);
} }
} }
@ -209,13 +209,11 @@ fn scroll_view(s: &str) {
scroll_view_lines_if_needed(v, false); scroll_view_lines_if_needed(v, false);
} }
fn view_text_value(value: &Spanned<Value>, source_map: &SourceMap) { fn view_text_value(value: &Tagged<Value>, source_map: &SourceMap) {
match value { let value_span = value.span();
Spanned { match value.item {
item: Value::Primitive(Primitive::String(s)), Value::Primitive(Primitive::String(ref s)) => {
span, let source = value_span.source.map(|x| source_map.get(&x)).flatten();
} => {
let source = span.source.map(|x| source_map.get(&x)).flatten();
if let Some(source) = source { if let Some(source) = source {
let extension: Option<String> = match source { let extension: Option<String> = match source {

View file

@ -1,6 +1,6 @@
use derive_new::new; use derive_new::new;
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{serve_plugin, CallInfo, CommandConfig, Plugin, ShellError, Spanned, Value}; use nu::{serve_plugin, CallInfo, CommandConfig, Plugin, ShellError, Tagged, Value};
use ptree::item::StringItem; use ptree::item::StringItem;
use ptree::output::print_tree_with; use ptree::output::print_tree_with;
use ptree::print_config::PrintConfig; use ptree::print_config::PrintConfig;
@ -91,7 +91,7 @@ impl Plugin for TreeViewer {
}) })
} }
fn sink(&mut self, _call_info: CallInfo, input: Vec<Spanned<Value>>) { fn sink(&mut self, _call_info: CallInfo, input: Vec<Tagged<Value>>) {
if input.len() > 0 { if input.len() > 0 {
for i in input.iter() { for i in input.iter() {
let view = TreeView::from_value(&i); let view = TreeView::from_value(&i);

View file

@ -36,14 +36,15 @@ crate use crate::cli::MaybeOwned;
crate use crate::commands::command::{ crate use crate::commands::command::{
Command, CommandAction, CommandArgs, ReturnSuccess, ReturnValue, Sink, SinkCommandArgs, Command, CommandAction, CommandArgs, ReturnSuccess, ReturnValue, Sink, SinkCommandArgs,
}; };
crate use crate::context::Context; crate use crate::context::{Context, SpanSource};
crate use crate::env::host::handle_unexpected; crate use crate::env::host::handle_unexpected;
crate use crate::env::{Environment, Host}; crate use crate::env::{Environment, Host};
crate use crate::errors::ShellError; crate use crate::errors::ShellError;
crate use crate::object::meta::{Tag, Tagged, TaggedItem};
crate use crate::object::types::ExtractType; crate use crate::object::types::ExtractType;
crate use crate::object::{Primitive, Value}; crate use crate::object::{Primitive, Value};
crate use crate::parser::{Span, Spanned, SpannedItem};
crate use crate::stream::{InputStream, OutputStream}; crate use crate::stream::{InputStream, OutputStream};
crate use crate::Span;
crate use crate::Text; crate use crate::Text;
crate use futures::stream::BoxStream; crate use futures::stream::BoxStream;
crate use futures::Stream; crate use futures::Stream;
@ -58,7 +59,7 @@ pub trait FromInputStream {
impl<T> FromInputStream for T impl<T> FromInputStream for T
where where
T: Stream<Item = Spanned<Value>> + Send + 'static, T: Stream<Item = Tagged<Value>> + Send + 'static,
{ {
fn from_input_stream(self) -> OutputStream { fn from_input_stream(self) -> OutputStream {
OutputStream { OutputStream {

View file

@ -1,10 +1,10 @@
use crate::parser::nom_input; use crate::parser::nom_input;
use crate::parser::parse::span::Spanned;
use crate::parser::parse::token_tree::TokenNode; use crate::parser::parse::token_tree::TokenNode;
use crate::parser::parse::tokens::RawToken; use crate::parser::parse::tokens::RawToken;
use crate::parser::{Pipeline, PipelineElement}; use crate::parser::{Pipeline, PipelineElement};
use crate::prelude::*; use crate::prelude::*;
use crate::shell::completer::NuCompleter; use crate::shell::completer::NuCompleter;
use crate::Tagged;
use ansi_term::Color; use ansi_term::Color;
use rustyline::completion::{self, Completer, FilenameCompleter}; use rustyline::completion::{self, Completer, FilenameCompleter};
use rustyline::error::ReadlineError; use rustyline::error::ReadlineError;
@ -107,23 +107,23 @@ fn paint_token_node(token_node: &TokenNode, line: &str) -> String {
TokenNode::Delimited(..) => Color::White.paint(token_node.span().slice(line)), TokenNode::Delimited(..) => Color::White.paint(token_node.span().slice(line)),
TokenNode::Operator(..) => Color::White.normal().paint(token_node.span().slice(line)), TokenNode::Operator(..) => Color::White.normal().paint(token_node.span().slice(line)),
TokenNode::Pipeline(..) => Color::Blue.normal().paint(token_node.span().slice(line)), TokenNode::Pipeline(..) => Color::Blue.normal().paint(token_node.span().slice(line)),
TokenNode::Token(Spanned { TokenNode::Token(Tagged {
item: RawToken::Integer(..), item: RawToken::Integer(..),
.. ..
}) => Color::Purple.bold().paint(token_node.span().slice(line)), }) => Color::Purple.bold().paint(token_node.span().slice(line)),
TokenNode::Token(Spanned { TokenNode::Token(Tagged {
item: RawToken::Size(..), item: RawToken::Size(..),
.. ..
}) => Color::Purple.bold().paint(token_node.span().slice(line)), }) => Color::Purple.bold().paint(token_node.span().slice(line)),
TokenNode::Token(Spanned { TokenNode::Token(Tagged {
item: RawToken::String(..), item: RawToken::String(..),
.. ..
}) => Color::Green.normal().paint(token_node.span().slice(line)), }) => Color::Green.normal().paint(token_node.span().slice(line)),
TokenNode::Token(Spanned { TokenNode::Token(Tagged {
item: RawToken::Variable(..), item: RawToken::Variable(..),
.. ..
}) => Color::Yellow.bold().paint(token_node.span().slice(line)), }) => Color::Yellow.bold().paint(token_node.span().slice(line)),
TokenNode::Token(Spanned { TokenNode::Token(Tagged {
item: RawToken::Bare, item: RawToken::Bare,
.. ..
}) => Color::Green.normal().paint(token_node.span().slice(line)), }) => Color::Green.normal().paint(token_node.span().slice(line)),

View file

@ -1,37 +1,37 @@
use crate::prelude::*; use crate::prelude::*;
pub struct InputStream { pub struct InputStream {
crate values: BoxStream<'static, Spanned<Value>>, crate values: BoxStream<'static, Tagged<Value>>,
} }
impl InputStream { impl InputStream {
pub fn into_vec(self) -> impl Future<Output = Vec<Spanned<Value>>> { pub fn into_vec(self) -> impl Future<Output = Vec<Tagged<Value>>> {
self.values.collect() self.values.collect()
} }
pub fn from_stream(input: impl Stream<Item = Spanned<Value>> + Send + 'static) -> InputStream { pub fn from_stream(input: impl Stream<Item = Tagged<Value>> + Send + 'static) -> InputStream {
InputStream { InputStream {
values: input.boxed(), values: input.boxed(),
} }
} }
} }
impl From<BoxStream<'static, Spanned<Value>>> for InputStream { impl From<BoxStream<'static, Tagged<Value>>> for InputStream {
fn from(input: BoxStream<'static, Spanned<Value>>) -> InputStream { fn from(input: BoxStream<'static, Tagged<Value>>) -> InputStream {
InputStream { values: input } InputStream { values: input }
} }
} }
impl From<VecDeque<Spanned<Value>>> for InputStream { impl From<VecDeque<Tagged<Value>>> for InputStream {
fn from(input: VecDeque<Spanned<Value>>) -> InputStream { fn from(input: VecDeque<Tagged<Value>>) -> InputStream {
InputStream { InputStream {
values: input.boxed(), values: input.boxed(),
} }
} }
} }
impl From<Vec<Spanned<Value>>> for InputStream { impl From<Vec<Tagged<Value>>> for InputStream {
fn from(input: Vec<Spanned<Value>>) -> InputStream { fn from(input: Vec<Tagged<Value>>) -> InputStream {
let mut list = VecDeque::default(); let mut list = VecDeque::default();
list.extend(input); list.extend(input);
@ -52,7 +52,7 @@ impl OutputStream {
v.into() v.into()
} }
pub fn from_input(input: impl Stream<Item = Spanned<Value>> + Send + 'static) -> OutputStream { pub fn from_input(input: impl Stream<Item = Tagged<Value>> + Send + 'static) -> OutputStream {
OutputStream { OutputStream {
values: input.map(ReturnSuccess::value).boxed(), values: input.map(ReturnSuccess::value).boxed(),
} }
@ -67,8 +67,8 @@ impl From<InputStream> for OutputStream {
} }
} }
impl From<BoxStream<'static, Spanned<Value>>> for OutputStream { impl From<BoxStream<'static, Tagged<Value>>> for OutputStream {
fn from(input: BoxStream<'static, Spanned<Value>>) -> OutputStream { fn from(input: BoxStream<'static, Tagged<Value>>) -> OutputStream {
OutputStream { OutputStream {
values: input.map(ReturnSuccess::value).boxed(), values: input.map(ReturnSuccess::value).boxed(),
} }
@ -89,8 +89,8 @@ impl From<VecDeque<ReturnValue>> for OutputStream {
} }
} }
impl From<VecDeque<Spanned<Value>>> for OutputStream { impl From<VecDeque<Tagged<Value>>> for OutputStream {
fn from(input: VecDeque<Spanned<Value>>) -> OutputStream { fn from(input: VecDeque<Tagged<Value>>) -> OutputStream {
OutputStream { OutputStream {
values: input values: input
.into_iter() .into_iter()
@ -112,8 +112,8 @@ impl From<Vec<ReturnValue>> for OutputStream {
} }
} }
impl From<Vec<Spanned<Value>>> for OutputStream { impl From<Vec<Tagged<Value>>> for OutputStream {
fn from(input: Vec<Spanned<Value>>) -> OutputStream { fn from(input: Vec<Tagged<Value>>) -> OutputStream {
let mut list = VecDeque::default(); let mut list = VecDeque::default();
list.extend(input.into_iter().map(ReturnSuccess::value)); list.extend(input.into_iter().map(ReturnSuccess::value));