diff --git a/Cargo.toml b/Cargo.toml index 09d654d45d..85a38c0e7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -161,7 +161,8 @@ table-pager = ["nu-command/table-pager"] #strip = "symbols" #Couldn't get working +nightly codegen-units = 1 #Reduce parallel codegen units lto = true #Link Time Optimization -opt-level = 'z' #Optimize for size +# opt-level = 'z' #Optimize for size +# debug = true # Core plugins that ship with `cargo install nu` by default # Currently, Cargo limits us to installing only one binary diff --git a/crates/nu-command/src/commands/ansi/command.rs b/crates/nu-command/src/commands/ansi/command.rs index 641ad835d4..15a49cab0a 100644 --- a/crates/nu-command/src/commands/ansi/command.rs +++ b/crates/nu-command/src/commands/ansi/command.rs @@ -115,12 +115,11 @@ Format: # fn run_with_actions(&self, args: CommandArgs) -> Result { let args = args.evaluate_once()?; - let code: Option, ShellError>> = args.opt(0); - let escape: Option, ShellError>> = args.get_flag("escape"); - let osc: Option, ShellError>> = args.get_flag("osc"); + let code: Option> = args.opt(0)?; + let escape: Option> = args.get_flag("escape")?; + let osc: Option> = args.get_flag("osc")?; if let Some(e) = escape { - let e = e?; let esc_vec: Vec = e.item.chars().collect(); if esc_vec[0] == '\\' { return Err(ShellError::labeled_error( @@ -136,7 +135,6 @@ Format: # } if let Some(o) = osc { - let o = o?; let osc_vec: Vec = o.item.chars().collect(); if osc_vec[0] == '\\' { return Err(ShellError::labeled_error( @@ -155,7 +153,6 @@ Format: # } if let Some(code) = code { - let code = code?; let ansi_code = str_to_ansi(&code.item); if let Some(output) = ansi_code { diff --git a/crates/nu-command/src/commands/enter.rs b/crates/nu-command/src/commands/enter.rs index ee55f6cdf6..c89ed359fe 100644 --- a/crates/nu-command/src/commands/enter.rs +++ b/crates/nu-command/src/commands/enter.rs @@ -129,19 +129,19 @@ fn enter(raw_args: CommandArgs) -> Result { scope, }; let tag = tagged_contents.tag.clone(); - let mut result = converter - .run_with_actions(new_args.with_input(vec![tagged_contents]))?; - let result_vec: Vec> = result.drain_vec(); + let mut result = + converter.run(new_args.with_input(vec![tagged_contents]))?; + let result_vec: Vec = result.drain_vec(); Ok(result_vec .into_iter() - .map(move |res| match res { - Ok(ReturnSuccess::Value(Value { value, .. })) => Ok( - ReturnSuccess::Action(CommandAction::EnterValueShell(Value { + .map(move |res| { + let Value { value, .. } = res; + Ok(ReturnSuccess::Action(CommandAction::EnterValueShell( + Value { value, tag: tag.clone(), - })), - ), - x => x, + }, + ))) }) .to_action_stream()) } else { diff --git a/crates/nu-command/src/commands/from.rs b/crates/nu-command/src/commands/from.rs index 23557029e8..bb79c48000 100644 --- a/crates/nu-command/src/commands/from.rs +++ b/crates/nu-command/src/commands/from.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{ReturnSuccess, Signature, UntaggedValue}; +use nu_protocol::{Signature, UntaggedValue}; pub struct From; @@ -18,10 +18,10 @@ impl WholeStreamCommand for From { "Parse content (string or binary) as a table (input format based on subcommand, like csv, ini, json, toml)." } - fn run_with_actions(&self, args: CommandArgs) -> Result { - Ok(ActionStream::one(ReturnSuccess::value( + fn run(&self, args: CommandArgs) -> Result { + Ok(OutputStream::one( UntaggedValue::string(get_full_help(&From, &args.scope)).into_value(Tag::unknown()), - ))) + )) } } diff --git a/crates/nu-command/src/commands/from_csv.rs b/crates/nu-command/src/commands/from_csv.rs index 2a21a0cb3d..d15e19ee62 100644 --- a/crates/nu-command/src/commands/from_csv.rs +++ b/crates/nu-command/src/commands/from_csv.rs @@ -6,12 +6,6 @@ use nu_protocol::{Primitive, Signature, SyntaxShape, UntaggedValue, Value}; pub struct FromCsv; -#[derive(Deserialize)] -pub struct FromCsvArgs { - noheaders: bool, - separator: Option, -} - impl WholeStreamCommand for FromCsv { fn name(&self) -> &str { "from csv" @@ -36,7 +30,7 @@ impl WholeStreamCommand for FromCsv { "Parse text as .csv and create table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_csv(args) } @@ -66,16 +60,14 @@ impl WholeStreamCommand for FromCsv { } } -fn from_csv(args: CommandArgs) -> Result { +fn from_csv(args: CommandArgs) -> Result { let name = args.call_info.name_tag.clone(); + let args = args.evaluate_once()?; + + let noheaders = args.has_flag("noheaders"); + let separator: Option = args.get_flag("separator")?; + let input = args.input; - let ( - FromCsvArgs { - noheaders, - separator, - }, - input, - ) = args.process()?; let sep = match separator { Some(Value { value: UntaggedValue::Primitive(Primitive::String(s)), diff --git a/crates/nu-command/src/commands/from_delimited_data.rs b/crates/nu-command/src/commands/from_delimited_data.rs index d4da775244..1a78afc704 100644 --- a/crates/nu-command/src/commands/from_delimited_data.rs +++ b/crates/nu-command/src/commands/from_delimited_data.rs @@ -51,7 +51,7 @@ pub fn from_delimited_data( format_name: &'static str, input: InputStream, name: Tag, -) -> Result { +) -> Result { let name_tag = name; let concat_string = input.collect_string(name_tag.clone())?; let sample_lines = concat_string.item.lines().take(3).collect_vec().join("\n"); @@ -61,8 +61,8 @@ pub fn from_delimited_data( Value { value: UntaggedValue::Table(list), .. - } => Ok(list.into_iter().to_action_stream()), - x => Ok(ActionStream::one(x)), + } => Ok(list.into_iter().to_output_stream()), + x => Ok(OutputStream::one(x)), }, Err(err) => { let line_one = match pretty_csv_error(err) { diff --git a/crates/nu-command/src/commands/from_eml.rs b/crates/nu-command/src/commands/from_eml.rs index d85419976e..7c8fc40be9 100644 --- a/crates/nu-command/src/commands/from_eml.rs +++ b/crates/nu-command/src/commands/from_eml.rs @@ -3,19 +3,13 @@ use ::eml_parser::eml::*; use ::eml_parser::EmlParser; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue}; +use nu_protocol::{Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue}; use nu_source::Tagged; pub struct FromEml; const DEFAULT_BODY_PREVIEW: usize = 50; -#[derive(Deserialize, Clone)] -pub struct FromEmlArgs { - #[serde(rename(deserialize = "preview-body"))] - preview_body: Option>, -} - impl WholeStreamCommand for FromEml { fn name(&self) -> &str { "from eml" @@ -34,7 +28,7 @@ impl WholeStreamCommand for FromEml { "Parse text as .eml and create table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_eml(args) } } @@ -72,15 +66,15 @@ fn headerfieldvalue_to_value(tag: &Tag, value: &HeaderFieldValue) -> UntaggedVal } } -fn from_eml(args: CommandArgs) -> Result { +fn from_eml(args: CommandArgs) -> Result { let tag = args.call_info.name_tag.clone(); - let (eml_args, input): (FromEmlArgs, _) = args.process()?; - let value = input.collect_string(tag.clone())?; + let args = args.evaluate_once()?; - let body_preview = eml_args - .preview_body - .map(|b| b.item) - .unwrap_or(DEFAULT_BODY_PREVIEW); + let preview_body: Option> = args.get_flag("preview-body")?; + + let value = args.input.collect_string(tag.clone())?; + + let body_preview = preview_body.map(|b| b.item).unwrap_or(DEFAULT_BODY_PREVIEW); let eml = EmlParser::from_string(value.item) .with_body_preview(body_preview) @@ -115,7 +109,7 @@ fn from_eml(args: CommandArgs) -> Result { dict.insert_untagged("Body", UntaggedValue::string(body)); } - Ok(ActionStream::one(ReturnSuccess::value(dict.into_value()))) + Ok(OutputStream::one(dict.into_value())) } #[cfg(test)] diff --git a/crates/nu-command/src/commands/from_ics.rs b/crates/nu-command/src/commands/from_ics.rs index a3cd403f2a..8d13b16432 100644 --- a/crates/nu-command/src/commands/from_ics.rs +++ b/crates/nu-command/src/commands/from_ics.rs @@ -4,7 +4,7 @@ use ical::parser::ical::component::*; use ical::property::Property; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{Primitive, ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue, Value}; +use nu_protocol::{Primitive, Signature, TaggedDictBuilder, UntaggedValue, Value}; use std::io::BufReader; pub struct FromIcs; @@ -22,12 +22,12 @@ impl WholeStreamCommand for FromIcs { "Parse text as .ics and create table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_ics(args) } } -fn from_ics(args: CommandArgs) -> Result { +fn from_ics(args: CommandArgs) -> Result { let args = args.evaluate_once()?; let tag = args.name_tag(); let input = args.input; @@ -43,8 +43,8 @@ fn from_ics(args: CommandArgs) -> Result { for calendar in parser { match calendar { - Ok(c) => output.push(ReturnSuccess::value(calendar_to_value(c, tag.clone()))), - Err(_) => output.push(Err(ShellError::labeled_error( + Ok(c) => output.push(calendar_to_value(c, tag.clone())), + Err(_) => output.push(Value::error(ShellError::labeled_error( "Could not parse as .ics", "input cannot be parsed as .ics", tag.clone(), @@ -52,7 +52,7 @@ fn from_ics(args: CommandArgs) -> Result { } } - Ok(output.into_iter().to_action_stream()) + Ok(output.into_iter().to_output_stream()) } fn calendar_to_value(calendar: IcalCalendar, tag: Tag) -> Value { diff --git a/crates/nu-command/src/commands/from_ini.rs b/crates/nu-command/src/commands/from_ini.rs index 9ee741d6e6..960a7e78cf 100644 --- a/crates/nu-command/src/commands/from_ini.rs +++ b/crates/nu-command/src/commands/from_ini.rs @@ -19,7 +19,7 @@ impl WholeStreamCommand for FromIni { "Parse text as .ini and create table" } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_ini(args) } } @@ -59,7 +59,7 @@ pub fn from_ini_string_to_value( Ok(convert_ini_top_to_nu_value(&v, tag)) } -fn from_ini(args: CommandArgs) -> Result { +fn from_ini(args: CommandArgs) -> Result { let args = args.evaluate_once()?; let tag = args.name_tag(); let input = args.input; @@ -70,8 +70,8 @@ fn from_ini(args: CommandArgs) -> Result { Value { value: UntaggedValue::Table(list), .. - } => Ok(list.into_iter().to_action_stream()), - x => Ok(ActionStream::one(x)), + } => Ok(list.into_iter().to_output_stream()), + x => Ok(OutputStream::one(x)), }, Err(_) => Err(ShellError::labeled_error_with_secondary( "Could not parse as INI", diff --git a/crates/nu-command/src/commands/from_json.rs b/crates/nu-command/src/commands/from_json.rs index b033d2720b..83caaa396b 100644 --- a/crates/nu-command/src/commands/from_json.rs +++ b/crates/nu-command/src/commands/from_json.rs @@ -1,15 +1,10 @@ use crate::prelude::*; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{Primitive, ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue, Value}; +use nu_protocol::{Primitive, Signature, TaggedDictBuilder, UntaggedValue, Value}; pub struct FromJson; -#[derive(Deserialize)] -pub struct FromJsonArgs { - objects: bool, -} - impl WholeStreamCommand for FromJson { fn name(&self) -> &str { "from json" @@ -27,7 +22,7 @@ impl WholeStreamCommand for FromJson { "Parse text as .json and create table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_json(args) } } @@ -67,11 +62,13 @@ pub fn from_json_string_to_value(s: String, tag: impl Into) -> nu_json::Res Ok(convert_json_value_to_nu_value(&v, tag)) } -fn from_json(args: CommandArgs) -> Result { +fn from_json(args: CommandArgs) -> Result { let name_tag = args.call_info.name_tag.clone(); - let (FromJsonArgs { objects }, input) = args.process()?; - let concat_string = input.collect_string(name_tag.clone())?; + let args = args.evaluate_once()?; + let objects = args.has_flag("objects"); + + let concat_string = args.input.collect_string(name_tag.clone())?; let string_clone: Vec<_> = concat_string.item.lines().map(|x| x.to_string()).collect(); @@ -84,13 +81,13 @@ fn from_json(args: CommandArgs) -> Result { } match from_json_string_to_value(json_str, &name_tag) { - Ok(x) => Some(ReturnSuccess::value(x)), + Ok(x) => Some(x), Err(e) => { let mut message = "Could not parse as JSON (".to_string(); message.push_str(&e.to_string()); message.push(')'); - Some(Err(ShellError::labeled_error_with_secondary( + Some(Value::error(ShellError::labeled_error_with_secondary( message, "input cannot be parsed as JSON", name_tag.clone(), @@ -100,26 +97,23 @@ fn from_json(args: CommandArgs) -> Result { } } }) - .to_action_stream()) + .to_output_stream()) } else { match from_json_string_to_value(concat_string.item, name_tag.clone()) { Ok(x) => match x { Value { value: UntaggedValue::Table(list), .. - } => Ok(list - .into_iter() - .map(ReturnSuccess::value) - .to_action_stream()), + } => Ok(list.into_iter().to_output_stream()), - x => Ok(ActionStream::one(ReturnSuccess::value(x))), + x => Ok(OutputStream::one(x)), }, Err(e) => { let mut message = "Could not parse as JSON (".to_string(); message.push_str(&e.to_string()); message.push(')'); - Ok(ActionStream::one(Err( + Ok(OutputStream::one(Value::error( ShellError::labeled_error_with_secondary( message, "input cannot be parsed as JSON", diff --git a/crates/nu-command/src/commands/from_ods.rs b/crates/nu-command/src/commands/from_ods.rs index 4929c2f5f7..c39fb29852 100644 --- a/crates/nu-command/src/commands/from_ods.rs +++ b/crates/nu-command/src/commands/from_ods.rs @@ -3,49 +3,34 @@ use calamine::*; use nu_data::TaggedListBuilder; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue}; +use nu_protocol::{Signature, TaggedDictBuilder, UntaggedValue}; use std::io::Cursor; pub struct FromOds; -#[derive(Deserialize)] -pub struct FromOdsArgs { - noheaders: bool, -} - impl WholeStreamCommand for FromOds { fn name(&self) -> &str { "from ods" } fn signature(&self) -> Signature { - Signature::build("from ods").switch( - "noheaders", - "don't treat the first row as column names", - Some('n'), - ) + Signature::build("from ods") } fn usage(&self) -> &str { "Parse OpenDocument Spreadsheet(.ods) data and create table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_ods(args) } } -fn from_ods(args: CommandArgs) -> Result { +fn from_ods(args: CommandArgs) -> Result { let tag = args.call_info.name_tag.clone(); let span = tag.span; - let ( - FromOdsArgs { - noheaders: _noheaders, - }, - input, - ) = args.process()?; - let bytes = input.collect_binary(tag.clone())?; + let bytes = args.input.collect_binary(tag.clone())?; let buf: Cursor> = Cursor::new(bytes.item); let mut ods = Ods::<_>::new(buf).map_err(|_| { ShellError::labeled_error("Could not load ods file", "could not load ods file", &tag) @@ -87,7 +72,7 @@ fn from_ods(args: CommandArgs) -> Result { } } - Ok(ActionStream::one(ReturnSuccess::value(dict.into_value()))) + Ok(OutputStream::one(dict.into_value())) } #[cfg(test)] diff --git a/crates/nu-command/src/commands/from_ssv.rs b/crates/nu-command/src/commands/from_ssv.rs index f470ce45c0..7d477210fa 100644 --- a/crates/nu-command/src/commands/from_ssv.rs +++ b/crates/nu-command/src/commands/from_ssv.rs @@ -1,22 +1,11 @@ use crate::prelude::*; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{ - Primitive, ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value, -}; +use nu_protocol::{Primitive, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value}; use nu_source::Tagged; pub struct FromSsv; -#[derive(Deserialize)] -pub struct FromSsvArgs { - noheaders: bool, - #[serde(rename(deserialize = "aligned-columns"))] - aligned_columns: bool, - #[serde(rename(deserialize = "minimum-spaces"))] - minimum_spaces: Option>, -} - const STRING_REPRESENTATION: &str = "from ssv"; const DEFAULT_MINIMUM_SPACES: usize = 2; @@ -45,7 +34,7 @@ impl WholeStreamCommand for FromSsv { "Parse text as space-separated values and create a table. The default minimum number of spaces counted as a separator is 2." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_ssv(args) } } @@ -246,17 +235,15 @@ fn from_ssv_string_to_value( UntaggedValue::Table(rows).into_value(&tag) } -fn from_ssv(args: CommandArgs) -> Result { +fn from_ssv(args: CommandArgs) -> Result { let name = args.call_info.name_tag.clone(); - let ( - FromSsvArgs { - noheaders, - aligned_columns, - minimum_spaces, - }, - input, - ) = args.process()?; - let concat_string = input.collect_string(name.clone())?; + let args = args.evaluate_once()?; + + let noheaders = args.has_flag("noheaders"); + let aligned_columns = args.has_flag("aligned-columns"); + let minimum_spaces: Option> = args.get_flag("minimum-spaces")?; + + let concat_string = args.input.collect_string(name.clone())?; let split_at = match minimum_spaces { Some(number) => number.item, None => DEFAULT_MINIMUM_SPACES, @@ -273,11 +260,8 @@ fn from_ssv(args: CommandArgs) -> Result { Value { value: UntaggedValue::Table(list), .. - } => list - .into_iter() - .map(ReturnSuccess::value) - .to_action_stream(), - x => ActionStream::one(ReturnSuccess::value(x)), + } => list.into_iter().to_output_stream(), + x => OutputStream::one(x), }, ) } diff --git a/crates/nu-command/src/commands/from_toml.rs b/crates/nu-command/src/commands/from_toml.rs index c7b9f997b2..872f4680f2 100644 --- a/crates/nu-command/src/commands/from_toml.rs +++ b/crates/nu-command/src/commands/from_toml.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{Primitive, ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue, Value}; +use nu_protocol::{Primitive, Signature, TaggedDictBuilder, UntaggedValue, Value}; pub struct FromToml; @@ -18,7 +18,7 @@ impl WholeStreamCommand for FromToml { "Parse text as .toml and create table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_toml(args) } } @@ -60,7 +60,7 @@ pub fn from_toml_string_to_value(s: String, tag: impl Into) -> Result Result { +pub fn from_toml(args: CommandArgs) -> Result { let args = args.evaluate_once()?; let tag = args.name_tag(); let input = args.input; @@ -72,11 +72,8 @@ pub fn from_toml(args: CommandArgs) -> Result { Value { value: UntaggedValue::Table(list), .. - } => list - .into_iter() - .map(ReturnSuccess::value) - .to_action_stream(), - x => ActionStream::one(ReturnSuccess::value(x)), + } => list.into_iter().to_output_stream(), + x => OutputStream::one(x), }, Err(_) => { return Err(ShellError::labeled_error_with_secondary( diff --git a/crates/nu-command/src/commands/from_tsv.rs b/crates/nu-command/src/commands/from_tsv.rs index 8b3df8aed1..da63836e5b 100644 --- a/crates/nu-command/src/commands/from_tsv.rs +++ b/crates/nu-command/src/commands/from_tsv.rs @@ -6,11 +6,6 @@ use nu_protocol::Signature; pub struct FromTsv; -#[derive(Deserialize)] -pub struct FromTsvArgs { - noheaders: bool, -} - impl WholeStreamCommand for FromTsv { fn name(&self) -> &str { "from tsv" @@ -28,14 +23,16 @@ impl WholeStreamCommand for FromTsv { "Parse text as .tsv and create table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_tsv(args) } } -fn from_tsv(args: CommandArgs) -> Result { +fn from_tsv(args: CommandArgs) -> Result { let name = args.call_info.name_tag.clone(); - let (FromTsvArgs { noheaders }, input) = args.process()?; + let args = args.evaluate_once()?; + let noheaders = args.has_flag("noheaders"); + let input = args.input; from_delimited_data(noheaders, '\t', "TSV", input, name) } diff --git a/crates/nu-command/src/commands/from_url.rs b/crates/nu-command/src/commands/from_url.rs index 9b5fd33317..7953b02612 100644 --- a/crates/nu-command/src/commands/from_url.rs +++ b/crates/nu-command/src/commands/from_url.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue}; +use nu_protocol::{Signature, TaggedDictBuilder, UntaggedValue}; pub struct FromUrl; @@ -18,12 +18,12 @@ impl WholeStreamCommand for FromUrl { "Parse url-encoded string as a table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_url(args) } } -fn from_url(args: CommandArgs) -> Result { +fn from_url(args: CommandArgs) -> Result { let args = args.evaluate_once()?; let tag = args.name_tag(); let input = args.input; @@ -40,7 +40,7 @@ fn from_url(args: CommandArgs) -> Result { row.insert_untagged(k, UntaggedValue::string(v)); } - Ok(ActionStream::one(ReturnSuccess::value(row.into_value()))) + Ok(OutputStream::one(row.into_value())) } _ => Err(ShellError::labeled_error_with_secondary( "String not compatible with url-encoding", diff --git a/crates/nu-command/src/commands/from_vcf.rs b/crates/nu-command/src/commands/from_vcf.rs index 5a28045b22..c628da53cb 100644 --- a/crates/nu-command/src/commands/from_vcf.rs +++ b/crates/nu-command/src/commands/from_vcf.rs @@ -1,10 +1,9 @@ -extern crate ical; use crate::prelude::*; use ical::parser::vcard::component::*; use ical::property::Property; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{Primitive, ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue, Value}; +use nu_protocol::{Primitive, Signature, TaggedDictBuilder, UntaggedValue, Value}; pub struct FromVcf; @@ -21,12 +20,12 @@ impl WholeStreamCommand for FromVcf { "Parse text as .vcf and create table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_vcf(args) } } -fn from_vcf(args: CommandArgs) -> Result { +fn from_vcf(args: CommandArgs) -> Result { let args = args.evaluate_once()?; let tag = args.name_tag(); let input = args.input; @@ -37,8 +36,8 @@ fn from_vcf(args: CommandArgs) -> Result { let parser = ical::VcardParser::new(cursor); let iter = parser.map(move |contact| match contact { - Ok(c) => ReturnSuccess::value(contact_to_value(c, tag.clone())), - Err(_) => Err(ShellError::labeled_error( + Ok(c) => contact_to_value(c, tag.clone()), + Err(_) => Value::error(ShellError::labeled_error( "Could not parse as .vcf", "input cannot be parsed as .vcf", tag.clone(), @@ -47,7 +46,7 @@ fn from_vcf(args: CommandArgs) -> Result { let collected: Vec<_> = iter.collect(); - Ok(collected.into_iter().to_action_stream()) + Ok(collected.into_iter().to_output_stream()) } fn contact_to_value(contact: VcardContact, tag: Tag) -> Value { diff --git a/crates/nu-command/src/commands/from_xlsx.rs b/crates/nu-command/src/commands/from_xlsx.rs index 6f5869efcb..a6ba395832 100644 --- a/crates/nu-command/src/commands/from_xlsx.rs +++ b/crates/nu-command/src/commands/from_xlsx.rs @@ -3,16 +3,11 @@ use calamine::*; use nu_data::TaggedListBuilder; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue}; +use nu_protocol::{Signature, TaggedDictBuilder, UntaggedValue}; use std::io::Cursor; pub struct FromXlsx; -#[derive(Deserialize)] -pub struct FromXlsxArgs { - noheaders: bool, -} - impl WholeStreamCommand for FromXlsx { fn name(&self) -> &str { "from xlsx" @@ -30,21 +25,16 @@ impl WholeStreamCommand for FromXlsx { "Parse binary Excel(.xlsx) data and create table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_xlsx(args) } } -fn from_xlsx(args: CommandArgs) -> Result { +fn from_xlsx(args: CommandArgs) -> Result { let tag = args.call_info.name_tag.clone(); let span = tag.span; - let ( - FromXlsxArgs { - noheaders: _noheaders, - }, - input, - ) = args.process()?; - let value = input.collect_binary(tag.clone())?; + + let value = args.input.collect_binary(tag.clone())?; let buf: Cursor> = Cursor::new(value.item); let mut xls = Xlsx::<_>::new(buf).map_err(|_| { @@ -87,7 +77,7 @@ fn from_xlsx(args: CommandArgs) -> Result { } } - Ok(ActionStream::one(ReturnSuccess::value(dict.into_value()))) + Ok(OutputStream::one(dict.into_value())) } #[cfg(test)] diff --git a/crates/nu-command/src/commands/from_xml.rs b/crates/nu-command/src/commands/from_xml.rs index b088359edd..b04a241ada 100644 --- a/crates/nu-command/src/commands/from_xml.rs +++ b/crates/nu-command/src/commands/from_xml.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{Primitive, ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue, Value}; +use nu_protocol::{Primitive, Signature, TaggedDictBuilder, UntaggedValue, Value}; pub struct FromXml; @@ -18,7 +18,7 @@ impl WholeStreamCommand for FromXml { "Parse text as .xml and create table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_xml(args) } } @@ -94,7 +94,7 @@ pub fn from_xml_string_to_value(s: String, tag: impl Into) -> Result Result { +fn from_xml(args: CommandArgs) -> Result { let args = args.evaluate_once()?; let tag = args.name_tag(); let input = args.input; @@ -107,11 +107,8 @@ fn from_xml(args: CommandArgs) -> Result { Value { value: UntaggedValue::Table(list), .. - } => list - .into_iter() - .map(ReturnSuccess::value) - .to_action_stream(), - x => ActionStream::one(ReturnSuccess::value(x)), + } => list.into_iter().to_output_stream(), + x => OutputStream::one(x), }, Err(_) => { return Err(ShellError::labeled_error_with_secondary( diff --git a/crates/nu-command/src/commands/from_yaml.rs b/crates/nu-command/src/commands/from_yaml.rs index f06f2bd9e0..d3a183a697 100644 --- a/crates/nu-command/src/commands/from_yaml.rs +++ b/crates/nu-command/src/commands/from_yaml.rs @@ -18,7 +18,7 @@ impl WholeStreamCommand for FromYaml { "Parse text as .yaml/.yml and create table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_yaml(args) } } @@ -38,7 +38,7 @@ impl WholeStreamCommand for FromYml { "Parse text as .yaml/.yml and create table." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { from_yaml(args) } } @@ -131,7 +131,7 @@ pub fn from_yaml_string_to_value(s: String, tag: impl Into) -> Result Result { +fn from_yaml(args: CommandArgs) -> Result { let args = args.evaluate_once()?; let tag = args.name_tag(); let input = args.input; @@ -143,8 +143,8 @@ fn from_yaml(args: CommandArgs) -> Result { Value { value: UntaggedValue::Table(list), .. - } => Ok(list.into_iter().to_action_stream()), - x => Ok(ActionStream::one(x)), + } => Ok(list.into_iter().to_output_stream()), + x => Ok(OutputStream::one(x)), }, Err(_) => Err(ShellError::labeled_error_with_secondary( "Could not parse as YAML", diff --git a/crates/nu-command/src/commands/math/eval.rs b/crates/nu-command/src/commands/math/eval.rs index 56e795f774..dda7c6212e 100644 --- a/crates/nu-command/src/commands/math/eval.rs +++ b/crates/nu-command/src/commands/math/eval.rs @@ -42,11 +42,11 @@ impl WholeStreamCommand for SubCommand { pub fn eval(args: CommandArgs) -> Result { let args = args.evaluate_once()?; - let expression: Option, ShellError>> = args.opt(0); + let expression: Option> = args.opt(0)?; let name = args.call_info.name_tag.clone(); let input = args.input; - if let Some(Ok(string)) = expression { + if let Some(string) = expression { match parse(&string, &string.tag) { Ok(value) => Ok(OutputStream::one(value)), Err(err) => Err(ShellError::labeled_error( @@ -58,10 +58,10 @@ pub fn eval(args: CommandArgs) -> Result { } else { let mapped: Result, _> = input .map(move |x| { - if let Some(Ok(Tagged { + if let Some(Tagged { tag, item: expression, - })) = &expression + }) = &expression { UntaggedValue::string(expression).into_value(tag) } else { diff --git a/crates/nu-command/src/commands/math/round.rs b/crates/nu-command/src/commands/math/round.rs index b10f6d07c0..ff6a698715 100644 --- a/crates/nu-command/src/commands/math/round.rs +++ b/crates/nu-command/src/commands/math/round.rs @@ -54,10 +54,10 @@ impl WholeStreamCommand for SubCommand { fn operate(args: CommandArgs) -> Result { let args = args.evaluate_once()?; - let precision: Option, ShellError>> = args.get_flag("precision"); + let precision: Option> = args.get_flag("precision")?; let input = args.input; let precision = if let Some(precision) = precision { - precision?.item + precision.item } else { 0 }; diff --git a/crates/nu-command/src/commands/save.rs b/crates/nu-command/src/commands/save.rs index edd84594b8..52fe20ba93 100644 --- a/crates/nu-command/src/commands/save.rs +++ b/crates/nu-command/src/commands/save.rs @@ -2,8 +2,7 @@ use crate::prelude::*; use nu_engine::{UnevaluatedCallInfo, WholeStreamCommand}; use nu_errors::ShellError; use nu_protocol::{ - hir::ExternalRedirection, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, - Value, + hir::ExternalRedirection, Primitive, Signature, SyntaxShape, UntaggedValue, Value, }; use nu_source::Tagged; use std::path::{Path, PathBuf}; @@ -81,10 +80,10 @@ macro_rules! process_string_return_success { let mut result_string = String::new(); for res in $result_vec { match res { - Ok(ReturnSuccess::Value(Value { + Value { value: UntaggedValue::Primitive(Primitive::String(s)), .. - })) => { + } => { result_string.push_str(&s); } _ => { @@ -105,10 +104,10 @@ macro_rules! process_binary_return_success { let mut result_binary: Vec = Vec::new(); for res in $result_vec { match res { - Ok(ReturnSuccess::Value(Value { + Value { value: UntaggedValue::Primitive(Primitive::Binary(b)), .. - })) => { + } => { for u in b.into_iter() { result_binary.push(u); } @@ -126,12 +125,6 @@ macro_rules! process_binary_return_success { }}; } -#[derive(Deserialize)] -pub struct SaveArgs { - path: Option>, - raw: bool, -} - impl WholeStreamCommand for Save { fn name(&self) -> &str { "save" @@ -155,12 +148,12 @@ impl WholeStreamCommand for Save { "Save the contents of the pipeline to a file." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { save(args) } } -fn save(raw_args: CommandArgs) -> Result { +fn save(raw_args: CommandArgs) -> Result { let mut full_path = PathBuf::from(raw_args.shell_manager.path()); let name_tag = raw_args.call_info.name_tag.clone(); let name = raw_args.call_info.name_tag.clone(); @@ -172,14 +165,12 @@ fn save(raw_args: CommandArgs) -> Result { let shell_manager = raw_args.shell_manager.clone(); let head = raw_args.call_info.args.head.clone(); - let ( - SaveArgs { - path, - raw: save_raw, - }, - input, - ) = raw_args.process()?; - let input: Vec = input.collect(); + let args = raw_args.evaluate_once()?; + + let path: Option> = args.opt(0)?; + let save_raw = args.has_flag("raw"); + + let input: Vec = args.input.collect(); if path.is_none() { let mut should_return_file_path_error = true; @@ -230,8 +221,8 @@ fn save(raw_args: CommandArgs) -> Result { }, scope, }; - let mut result = converter.run_with_actions(new_args.with_input(input))?; - let result_vec: Vec> = result.drain_vec(); + let mut result = converter.run(new_args.with_input(input))?; + let result_vec: Vec = result.drain_vec(); if converter.is_binary() { process_binary_return_success!('scope, result_vec, name_tag) } else { diff --git a/crates/nu-command/src/commands/select.rs b/crates/nu-command/src/commands/select.rs index e2f4e11246..5b5a9a8e7b 100644 --- a/crates/nu-command/src/commands/select.rs +++ b/crates/nu-command/src/commands/select.rs @@ -3,16 +3,11 @@ use crate::utils::arguments::arguments; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; use nu_protocol::{ - PathMember, Primitive, ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, - UnspannedPathMember, UntaggedValue, Value, + PathMember, Primitive, Signature, SyntaxShape, TaggedDictBuilder, UnspannedPathMember, + UntaggedValue, Value, }; use nu_value_ext::{as_string, get_data_by_column_path}; -#[derive(Deserialize)] -struct Arguments { - rest: Vec, -} - pub struct Command; impl WholeStreamCommand for Command { @@ -28,7 +23,7 @@ impl WholeStreamCommand for Command { "Down-select table to only these columns." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { select(args) } @@ -48,9 +43,11 @@ impl WholeStreamCommand for Command { } } -fn select(args: CommandArgs) -> Result { +fn select(args: CommandArgs) -> Result { let name = args.call_info.name_tag.clone(); - let (Arguments { mut rest }, input) = args.process()?; + let args = args.evaluate_once()?; + let mut rest = args.rest(0)?; + let input = args.input; let (columns, _) = arguments(&mut rest)?; if columns.is_empty() { @@ -153,7 +150,7 @@ fn select(args: CommandArgs) -> Result { } } - ReturnSuccess::value(out.into_value()) + out.into_value() })) - .to_action_stream()) + .to_output_stream()) } diff --git a/crates/nu-command/src/commands/str_/collect.rs b/crates/nu-command/src/commands/str_/collect.rs index 3960daf59d..8f5d94bc45 100644 --- a/crates/nu-command/src/commands/str_/collect.rs +++ b/crates/nu-command/src/commands/str_/collect.rs @@ -51,11 +51,7 @@ pub fn collect(args: CommandArgs) -> Result { let (options, input) = args.extract(|params| { Ok(Arguments { - separator: if let Some(arg) = params.opt(0) { - Some(arg?) - } else { - None - }, + separator: params.opt(0)?, }) })?; diff --git a/crates/nu-command/src/commands/str_/from.rs b/crates/nu-command/src/commands/str_/from.rs index 84fa448850..bdfa95ac72 100644 --- a/crates/nu-command/src/commands/str_/from.rs +++ b/crates/nu-command/src/commands/str_/from.rs @@ -71,11 +71,7 @@ impl WholeStreamCommand for SubCommand { fn operate(args: CommandArgs) -> Result { let (options, input) = args.extract(|params| { Ok(Arguments { - decimals: if let Some(arg) = params.get_flag("decimals") { - Some(arg?) - } else { - None - }, + decimals: params.get_flag("decimals")?, group_digits: false, column_paths: params.rest_args()?, }) diff --git a/crates/nu-command/src/commands/str_/index_of.rs b/crates/nu-command/src/commands/str_/index_of.rs index f0b8f1fd79..035d0af4cf 100644 --- a/crates/nu-command/src/commands/str_/index_of.rs +++ b/crates/nu-command/src/commands/str_/index_of.rs @@ -93,11 +93,7 @@ fn operate(args: CommandArgs) -> Result { let (options, input) = args.extract(|params| { Ok(Arc::new(Arguments { pattern: params.req(0)?, - range: if let Some(arg) = params.get_flag("range") { - Some(arg?) - } else { - None - }, + range: params.get_flag("range")?, end: params.has_flag("end"), column_paths: params.rest(1)?, })) diff --git a/crates/nu-command/src/commands/str_/to_datetime.rs b/crates/nu-command/src/commands/str_/to_datetime.rs index 3f089ca0af..7d31f94063 100644 --- a/crates/nu-command/src/commands/str_/to_datetime.rs +++ b/crates/nu-command/src/commands/str_/to_datetime.rs @@ -131,21 +131,9 @@ fn operate(args: CommandArgs) -> Result { let (column_paths, _) = arguments(&mut params.rest_args()?)?; Ok(Arguments { - timezone: if let Some(arg) = params.get_flag("timezone") { - Some(arg?) - } else { - None - }, - offset: if let Some(arg) = params.get_flag("offset") { - Some(arg?) - } else { - None - }, - format: if let Some(arg) = params.get_flag("format") { - Some(arg?) - } else { - None - }, + timezone: params.get_flag("timezone")?, + offset: params.get_flag("offset")?, + format: params.get_flag("format")?, column_paths, }) })?; diff --git a/crates/nu-command/src/commands/str_/to_integer.rs b/crates/nu-command/src/commands/str_/to_integer.rs index ccdb36eb03..ae0e230732 100644 --- a/crates/nu-command/src/commands/str_/to_integer.rs +++ b/crates/nu-command/src/commands/str_/to_integer.rs @@ -72,11 +72,7 @@ fn operate(args: CommandArgs) -> Result { let (column_paths, _) = arguments(&mut params.rest_args()?)?; Ok(Arguments { - radix: if let Some(arg) = params.get_flag("radix") { - Some(arg?) - } else { - None - }, + radix: params.get_flag("radix")?, column_paths, }) })?; diff --git a/crates/nu-command/src/commands/str_/trim/mod.rs b/crates/nu-command/src/commands/str_/trim/mod.rs index 55680593a6..c05b3272f7 100644 --- a/crates/nu-command/src/commands/str_/trim/mod.rs +++ b/crates/nu-command/src/commands/str_/trim/mod.rs @@ -25,11 +25,7 @@ where { let (options, input) = args.extract(|params| { Ok(Arc::new(Arguments { - character: if let Some(arg) = params.get_flag("char") { - Some(arg?) - } else { - None - }, + character: params.get_flag("char")?, column_paths: params.rest_args()?, })) })?; diff --git a/crates/nu-command/src/commands/table/command.rs b/crates/nu-command/src/commands/table/command.rs index a7fb1fd288..f0739ba740 100644 --- a/crates/nu-command/src/commands/table/command.rs +++ b/crates/nu-command/src/commands/table/command.rs @@ -176,8 +176,8 @@ fn table(args: CommandArgs) -> Result { // config.toml.... yet. let color_hm = get_color_config(&configuration); - let mut start_number = if let Some(f) = args.get_flag("start_number") { - f? + let mut start_number = if let Some(f) = args.get_flag("start_number")? { + f } else { 0 }; diff --git a/crates/nu-command/src/commands/to.rs b/crates/nu-command/src/commands/to.rs index 14d5fba978..5f04729819 100644 --- a/crates/nu-command/src/commands/to.rs +++ b/crates/nu-command/src/commands/to.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{ReturnSuccess, Signature, UntaggedValue}; +use nu_protocol::{Signature, UntaggedValue}; #[derive(Clone)] pub struct To; @@ -19,10 +19,10 @@ impl WholeStreamCommand for To { "Convert table into an output format (based on subcommand, like csv, html, json, yaml)." } - fn run_with_actions(&self, args: CommandArgs) -> Result { - Ok(ActionStream::one(ReturnSuccess::value( + fn run(&self, args: CommandArgs) -> Result { + Ok(OutputStream::one( UntaggedValue::string(get_full_help(&To, &args.scope)).into_value(Tag::unknown()), - ))) + )) } } diff --git a/crates/nu-command/src/commands/to_csv.rs b/crates/nu-command/src/commands/to_csv.rs index 9a37693ff1..ad20a0a200 100644 --- a/crates/nu-command/src/commands/to_csv.rs +++ b/crates/nu-command/src/commands/to_csv.rs @@ -6,12 +6,6 @@ use nu_protocol::{Primitive, Signature, SyntaxShape, UntaggedValue, Value}; pub struct ToCsv; -#[derive(Deserialize)] -pub struct ToCsvArgs { - noheaders: bool, - separator: Option, -} - impl WholeStreamCommand for ToCsv { fn name(&self) -> &str { "to csv" @@ -36,20 +30,17 @@ impl WholeStreamCommand for ToCsv { "Convert table into .csv text " } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { to_csv(args) } } -fn to_csv(args: CommandArgs) -> Result { +fn to_csv(args: CommandArgs) -> Result { let name = args.call_info.name_tag.clone(); - let ( - ToCsvArgs { - separator, - noheaders, - }, - input, - ) = args.process()?; + let args = args.evaluate_once()?; + let separator: Option = args.get_flag("separator")?; + let noheaders = args.has_flag("noheaders"); + let input = args.input; let sep = match separator { Some(Value { value: UntaggedValue::Primitive(Primitive::String(s)), diff --git a/crates/nu-command/src/commands/to_delimited_data.rs b/crates/nu-command/src/commands/to_delimited_data.rs index cc00c695e9..b121393d7f 100644 --- a/crates/nu-command/src/commands/to_delimited_data.rs +++ b/crates/nu-command/src/commands/to_delimited_data.rs @@ -2,7 +2,7 @@ use crate::prelude::*; use csv::WriterBuilder; use indexmap::{indexset, IndexSet}; use nu_errors::ShellError; -use nu_protocol::{Primitive, ReturnSuccess, UntaggedValue, Value}; +use nu_protocol::{Primitive, UntaggedValue, Value}; use nu_source::Spanned; use nu_value_ext::{as_string, ValueExt}; @@ -170,7 +170,7 @@ pub fn to_delimited_data( format_name: &'static str, input: InputStream, name: Tag, -) -> Result { +) -> Result { let name_tag = name; let name_span = name_tag.span; @@ -197,9 +197,7 @@ pub fn to_delimited_data( x.replace_range(0..start, ""); } } - ReturnSuccess::value( - UntaggedValue::Primitive(Primitive::String(x)).into_value(&name_tag), - ) + UntaggedValue::Primitive(Primitive::String(x)).into_value(&name_tag) } Err(_) => { let expected = format!( @@ -207,7 +205,7 @@ pub fn to_delimited_data( format_name ); let requires = format!("requires {}-compatible input", format_name); - Err(ShellError::labeled_error_with_secondary( + Value::error(ShellError::labeled_error_with_secondary( expected, requires, name_span, @@ -217,5 +215,5 @@ pub fn to_delimited_data( } } })) - .to_action_stream()) + .to_output_stream()) } diff --git a/crates/nu-command/src/commands/to_html.rs b/crates/nu-command/src/commands/to_html.rs index 637a3e9f18..b790a29585 100644 --- a/crates/nu-command/src/commands/to_html.rs +++ b/crates/nu-command/src/commands/to_html.rs @@ -3,7 +3,7 @@ use crate::prelude::*; use nu_data::value::format_leaf; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value}; +use nu_protocol::{Primitive, Signature, SyntaxShape, UntaggedValue, Value}; use nu_source::{AnchorLocation, Tagged}; use regex::Regex; use rust_embed::RustEmbed; @@ -81,16 +81,6 @@ struct Assets; pub struct ToHtml; -#[derive(Deserialize)] -pub struct ToHtmlArgs { - html_color: bool, - no_color: bool, - dark: bool, - partial: bool, - theme: Option>, - list: bool, -} - impl WholeStreamCommand for ToHtml { fn name(&self) -> &str { "to html" @@ -123,7 +113,7 @@ impl WholeStreamCommand for ToHtml { "Convert table into simple HTML" } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { to_html(args) } } @@ -267,20 +257,17 @@ fn get_list_of_theme_names() -> Vec { theme_names } -fn to_html(args: CommandArgs) -> Result { +fn to_html(args: CommandArgs) -> Result { let name_tag = args.call_info.name_tag.clone(); - let ( - ToHtmlArgs { - html_color, - no_color, - dark, - partial, - theme, - list, - }, - input, - ) = args.process()?; - let input: Vec = input.collect(); + let args = args.evaluate_once()?; + let html_color = args.has_flag("html_color"); + let no_color = args.has_flag("no_color"); + let dark = args.has_flag("dark"); + let partial = args.has_flag("partial"); + let list = args.has_flag("list"); + let theme: Option> = args.get_flag("theme")?; + + let input: Vec = args.input.collect(); let headers = nu_protocol::merge_descriptors(&input); let headers = Some(headers) .filter(|headers| !headers.is_empty() && (headers.len() > 1 || !headers[0].is_empty())); @@ -300,9 +287,9 @@ fn to_html(args: CommandArgs) -> Result { output_string.push_str("https://github.com/mbadolato/iTerm2-Color-Schemes\n"); // Short circuit and return the output_string - Ok(ActionStream::one(ReturnSuccess::value( + Ok(OutputStream::one( UntaggedValue::string(output_string).into_value(name_tag), - ))) + )) } else { let theme_tag = match &theme { Some(v) => &v.tag, @@ -376,9 +363,9 @@ fn to_html(args: CommandArgs) -> Result { output_string = run_regexes(®ex_hm, &output_string); } - Ok(ActionStream::one(ReturnSuccess::value( + Ok(OutputStream::one( UntaggedValue::string(output_string).into_value(name_tag), - ))) + )) } } diff --git a/crates/nu-command/src/commands/to_json.rs b/crates/nu-command/src/commands/to_json.rs index d1c4a82a21..e03e1f5154 100644 --- a/crates/nu-command/src/commands/to_json.rs +++ b/crates/nu-command/src/commands/to_json.rs @@ -1,19 +1,12 @@ use crate::prelude::*; use nu_engine::WholeStreamCommand; use nu_errors::{CoerceInto, ShellError}; -use nu_protocol::{ - Primitive, ReturnSuccess, Signature, SyntaxShape, UnspannedPathMember, UntaggedValue, Value, -}; +use nu_protocol::{Primitive, Signature, SyntaxShape, UnspannedPathMember, UntaggedValue, Value}; use serde::Serialize; use serde_json::json; pub struct ToJson; -#[derive(Deserialize)] -pub struct ToJsonArgs { - pretty: Option, -} - impl WholeStreamCommand for ToJson { fn name(&self) -> &str { "to json" @@ -32,7 +25,7 @@ impl WholeStreamCommand for ToJson { "Converts table data into JSON text." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { to_json(args) } @@ -157,11 +150,13 @@ fn json_list(input: &[Value]) -> Result, ShellError> { Ok(out) } -fn to_json(args: CommandArgs) -> Result { +fn to_json(args: CommandArgs) -> Result { let name_tag = args.call_info.name_tag.clone(); - let (ToJsonArgs { pretty }, input) = args.process()?; + let args = args.evaluate_once()?; + let pretty: Option = args.get_flag("pretty")?; + let name_span = name_tag.span; - let input: Vec = input.collect(); + let input: Vec = args.input.collect(); let to_process_input = match input.len() { x if x > 1 => { @@ -221,7 +216,7 @@ fn to_json(args: CommandArgs) -> Result { } if pretty_format_failed { - return Err(ShellError::labeled_error( + return Value::error(ShellError::labeled_error( "Pretty formatting failed", "failed", pretty_value.tag(), @@ -229,12 +224,10 @@ fn to_json(args: CommandArgs) -> Result { } } - ReturnSuccess::value( - UntaggedValue::Primitive(Primitive::String(serde_json_string)) - .into_value(&value.tag), - ) + UntaggedValue::Primitive(Primitive::String(serde_json_string)) + .into_value(&value.tag) } - _ => Err(ShellError::labeled_error_with_secondary( + _ => Value::error(ShellError::labeled_error_with_secondary( "Expected a table with JSON-compatible structure.tag() from pipeline", "requires JSON-compatible input", name_span, @@ -243,13 +236,13 @@ fn to_json(args: CommandArgs) -> Result { )), } } - _ => Err(ShellError::labeled_error( + _ => Value::error(ShellError::labeled_error( "Expected a table with JSON-compatible structure from pipeline", "requires JSON-compatible input", &name_tag, )), })) - .to_action_stream()) + .to_output_stream()) } #[cfg(test)] diff --git a/crates/nu-command/src/commands/to_md.rs b/crates/nu-command/src/commands/to_md.rs index af5e4594c2..2628d91aff 100644 --- a/crates/nu-command/src/commands/to_md.rs +++ b/crates/nu-command/src/commands/to_md.rs @@ -3,7 +3,7 @@ use crate::prelude::*; use nu_data::value::format_leaf; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{ReturnSuccess, Signature, UntaggedValue, Value}; +use nu_protocol::{Signature, UntaggedValue, Value}; pub struct Command; @@ -37,7 +37,7 @@ impl WholeStreamCommand for Command { "Convert table into simple Markdown" } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { to_md(args) } @@ -82,19 +82,23 @@ impl WholeStreamCommand for Command { } } -fn to_md(args: CommandArgs) -> Result { +fn to_md(args: CommandArgs) -> Result { let name_tag = args.call_info.name_tag.clone(); - let (arguments, input) = args.process()?; + let args = args.evaluate_once()?; + let arguments = Arguments { + per_element: args.has_flag("per-element"), + pretty: args.has_flag("pretty"), + }; - let input: Vec = input.collect(); + let input: Vec = args.input.collect(); - Ok(ActionStream::one(ReturnSuccess::value( + Ok(OutputStream::one( UntaggedValue::string(process(&input, arguments)).into_value(if input.is_empty() { name_tag } else { input[0].tag() }), - ))) + )) } fn process( diff --git a/crates/nu-command/src/commands/to_toml.rs b/crates/nu-command/src/commands/to_toml.rs index e1ea25b9ce..b0cd99d682 100644 --- a/crates/nu-command/src/commands/to_toml.rs +++ b/crates/nu-command/src/commands/to_toml.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use nu_engine::WholeStreamCommand; use nu_errors::{CoerceInto, ShellError}; -use nu_protocol::{Primitive, ReturnSuccess, Signature, UnspannedPathMember, UntaggedValue, Value}; +use nu_protocol::{Primitive, Signature, UnspannedPathMember, UntaggedValue, Value}; pub struct ToToml; @@ -18,20 +18,9 @@ impl WholeStreamCommand for ToToml { "Convert table into .toml text" } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { to_toml(args) } - // TODO: add an example here. What commands to run to get a Row(Dictionary)? - // fn examples(&self) -> Vec { - // vec![ - // Example { - // description: - // "Outputs an TOML string representing TOML document", - // example: "echo [1 2 3] | to json", - // result: Some(vec![Value::from("[1,2,3]")]), - // }, - // ] - // } } // Helper method to recursively convert nu_protocol::Value -> toml::Value @@ -139,7 +128,7 @@ fn collect_values(input: &[Value]) -> Result, ShellError> { Ok(out) } -fn to_toml(args: CommandArgs) -> Result { +fn to_toml(args: CommandArgs) -> Result { let args = args.evaluate_once()?; let name_tag = args.name_tag(); let name_span = name_tag.span; @@ -161,10 +150,9 @@ fn to_toml(args: CommandArgs) -> Result { let value_span = value.tag.span; match value_to_toml_value(&value) { Ok(toml_value) => match toml::to_string(&toml_value) { - Ok(x) => ReturnSuccess::value( - UntaggedValue::Primitive(Primitive::String(x)).into_value(&name_tag), - ), - _ => Err(ShellError::labeled_error_with_secondary( + Ok(x) => UntaggedValue::Primitive(Primitive::String(x)).into_value(&name_tag), + + _ => Value::error(ShellError::labeled_error_with_secondary( "Expected a table with TOML-compatible structure.tag() from pipeline", "requires TOML-compatible input", name_span, @@ -172,14 +160,14 @@ fn to_toml(args: CommandArgs) -> Result { value_span, )), }, - _ => Err(ShellError::labeled_error( + _ => Value::error(ShellError::labeled_error( "Expected a table with TOML-compatible structure from pipeline", "requires TOML-compatible input", &name_tag, )), } })) - .to_action_stream()) + .to_output_stream()) } #[cfg(test)] diff --git a/crates/nu-command/src/commands/to_tsv.rs b/crates/nu-command/src/commands/to_tsv.rs index 803748ba4a..6a025a428d 100644 --- a/crates/nu-command/src/commands/to_tsv.rs +++ b/crates/nu-command/src/commands/to_tsv.rs @@ -6,11 +6,6 @@ use nu_protocol::Signature; pub struct ToTsv; -#[derive(Deserialize)] -pub struct ToTsvArgs { - noheaders: bool, -} - impl WholeStreamCommand for ToTsv { fn name(&self) -> &str { "to tsv" @@ -28,16 +23,17 @@ impl WholeStreamCommand for ToTsv { "Convert table into .tsv text" } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { to_tsv(args) } } -fn to_tsv(args: CommandArgs) -> Result { +fn to_tsv(args: CommandArgs) -> Result { let name = args.call_info.name_tag.clone(); - let (ToTsvArgs { noheaders }, input) = args.process()?; + let args = args.evaluate_once()?; + let noheaders = args.has_flag("noheaders"); - to_delimited_data(noheaders, '\t', "TSV", input, name) + to_delimited_data(noheaders, '\t', "TSV", args.input, name) } #[cfg(test)] diff --git a/crates/nu-command/src/commands/to_url.rs b/crates/nu-command/src/commands/to_url.rs index 22cc3a7b37..432df3464e 100644 --- a/crates/nu-command/src/commands/to_url.rs +++ b/crates/nu-command/src/commands/to_url.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{ReturnSuccess, Signature, UntaggedValue, Value}; +use nu_protocol::{Signature, UntaggedValue, Value}; pub struct ToUrl; @@ -18,12 +18,12 @@ impl WholeStreamCommand for ToUrl { "Convert table into url-encoded text" } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { to_url(args) } } -fn to_url(args: CommandArgs) -> Result { +fn to_url(args: CommandArgs) -> Result { let args = args.evaluate_once()?; let tag = args.name_tag(); let input = args.input; @@ -41,7 +41,7 @@ fn to_url(args: CommandArgs) -> Result { row_vec.push((k.clone(), s.to_string())); } _ => { - return Err(ShellError::labeled_error_with_secondary( + return Value::error(ShellError::labeled_error_with_secondary( "Expected table with string values", "requires table with strings", &tag, @@ -53,15 +53,15 @@ fn to_url(args: CommandArgs) -> Result { } match serde_urlencoded::to_string(row_vec) { - Ok(s) => ReturnSuccess::value(UntaggedValue::string(s).into_value(&tag)), - _ => Err(ShellError::labeled_error( + Ok(s) => UntaggedValue::string(s).into_value(&tag), + _ => Value::error(ShellError::labeled_error( "Failed to convert to url-encoded", "cannot url-encode", &tag, )), } } - Value { tag: value_tag, .. } => Err(ShellError::labeled_error_with_secondary( + Value { tag: value_tag, .. } => Value::error(ShellError::labeled_error_with_secondary( "Expected a table from pipeline", "requires table input", &tag, @@ -69,7 +69,7 @@ fn to_url(args: CommandArgs) -> Result { value_tag.span, )), }) - .to_action_stream()) + .to_output_stream()) } #[cfg(test)] diff --git a/crates/nu-command/src/commands/to_xml.rs b/crates/nu-command/src/commands/to_xml.rs index 340d5263ab..b8db63e0d4 100644 --- a/crates/nu-command/src/commands/to_xml.rs +++ b/crates/nu-command/src/commands/to_xml.rs @@ -2,7 +2,7 @@ use crate::prelude::*; use indexmap::IndexMap; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value}; +use nu_protocol::{Primitive, Signature, SyntaxShape, UntaggedValue, Value}; use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event}; use std::collections::HashSet; use std::io::Cursor; @@ -10,11 +10,6 @@ use std::io::Write; pub struct ToXml; -#[derive(Deserialize)] -pub struct ToXmlArgs { - pretty: Option, -} - impl WholeStreamCommand for ToXml { fn name(&self) -> &str { "to xml" @@ -33,7 +28,7 @@ impl WholeStreamCommand for ToXml { "Convert table into .xml text" } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { to_xml(args) } } @@ -131,11 +126,12 @@ pub fn write_xml_events( Ok(()) } -fn to_xml(args: CommandArgs) -> Result { +fn to_xml(args: CommandArgs) -> Result { let name_tag = args.call_info.name_tag.clone(); let name_span = name_tag.span; - let (ToXmlArgs { pretty }, input) = args.process()?; - let input: Vec = input.collect(); + let args = args.evaluate_once()?; + let pretty: Option = args.get_flag("pretty")?; + let input: Vec = args.input.collect(); let to_process_input = match input.len() { x if x > 1 => { @@ -166,12 +162,16 @@ fn to_xml(args: CommandArgs) -> Result { match write_xml_events(&value, &mut w) { Ok(_) => { let b = w.into_inner().into_inner(); - let s = String::from_utf8(b)?; - ReturnSuccess::value( - UntaggedValue::Primitive(Primitive::String(s)).into_value(&name_tag), - ) + let s = if let Ok(s) = String::from_utf8(b) { + s + } else { + return Value::error(ShellError::untagged_runtime_error( + "Could not convert a string to utf-8", + )); + }; + UntaggedValue::Primitive(Primitive::String(s)).into_value(&name_tag) } - Err(_) => Err(ShellError::labeled_error_with_secondary( + Err(_) => Value::error(ShellError::labeled_error_with_secondary( "Expected a table with XML-compatible structure from pipeline", "requires XML-compatible input", name_span, @@ -180,7 +180,7 @@ fn to_xml(args: CommandArgs) -> Result { )), } })) - .to_action_stream()) + .to_output_stream()) } #[cfg(test)] diff --git a/crates/nu-command/src/commands/to_yaml.rs b/crates/nu-command/src/commands/to_yaml.rs index a4ebbb23f3..7668d3e752 100644 --- a/crates/nu-command/src/commands/to_yaml.rs +++ b/crates/nu-command/src/commands/to_yaml.rs @@ -1,7 +1,7 @@ use crate::prelude::*; use nu_engine::WholeStreamCommand; use nu_errors::{CoerceInto, ShellError}; -use nu_protocol::{Primitive, ReturnSuccess, Signature, UnspannedPathMember, UntaggedValue, Value}; +use nu_protocol::{Primitive, Signature, UnspannedPathMember, UntaggedValue, Value}; pub struct ToYaml; @@ -18,7 +18,7 @@ impl WholeStreamCommand for ToYaml { "Convert table into .yaml/.yml text" } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { to_yaml(args) } } @@ -113,7 +113,7 @@ pub fn value_to_yaml_value(v: &Value) -> Result { }) } -fn to_yaml(args: CommandArgs) -> Result { +fn to_yaml(args: CommandArgs) -> Result { let args = args.evaluate_once()?; let name_tag = args.name_tag(); let name_span = name_tag.span; @@ -137,10 +137,9 @@ fn to_yaml(args: CommandArgs) -> Result { match value_to_yaml_value(&value) { Ok(yaml_value) => match serde_yaml::to_string(&yaml_value) { - Ok(x) => ReturnSuccess::value( - UntaggedValue::Primitive(Primitive::String(x)).into_value(&name_tag), - ), - _ => Err(ShellError::labeled_error_with_secondary( + Ok(x) => UntaggedValue::Primitive(Primitive::String(x)).into_value(&name_tag), + + _ => Value::error(ShellError::labeled_error_with_secondary( "Expected a table with YAML-compatible structure from pipeline", "requires YAML-compatible input", name_span, @@ -148,14 +147,14 @@ fn to_yaml(args: CommandArgs) -> Result { value_span, )), }, - _ => Err(ShellError::labeled_error( + _ => Value::error(ShellError::labeled_error( "Expected a table with YAML-compatible structure from pipeline", "requires YAML-compatible input", &name_tag, )), } })) - .to_action_stream()) + .to_output_stream()) } #[cfg(test)] diff --git a/crates/nu-engine/src/command_args.rs b/crates/nu-engine/src/command_args.rs index cfaee5ba60..ee8d410f35 100644 --- a/crates/nu-engine/src/command_args.rs +++ b/crates/nu-engine/src/command_args.rs @@ -229,11 +229,12 @@ impl EvaluatedCommandArgs { .ok_or_else(|| ShellError::unimplemented("Better error: expect_nth")) } - pub fn get_flag(&self, name: &str) -> Option> { - self.call_info - .args - .get(name) - .map(|x| FromValue::from_value(x)) + pub fn get_flag(&self, name: &str) -> Result, ShellError> { + if let Some(arg) = self.call_info.args.get(name) { + FromValue::from_value(arg).map(Some) + } else { + Ok(None) + } } pub fn req_named(&self, name: &str) -> Result { @@ -259,11 +260,11 @@ impl EvaluatedCommandArgs { } } - pub fn opt(&self, pos: usize) -> Option> { + pub fn opt(&self, pos: usize) -> Result, ShellError> { if let Some(v) = self.nth(pos) { - Some(FromValue::from_value(v)) + FromValue::from_value(v).map(Some) } else { - None + Ok(None) } } diff --git a/crates/nu-engine/src/evaluate/block.rs b/crates/nu-engine/src/evaluate/block.rs index dc85311877..efd65ac662 100644 --- a/crates/nu-engine/src/evaluate/block.rs +++ b/crates/nu-engine/src/evaluate/block.rs @@ -6,9 +6,8 @@ use nu_parser::ParserScope; use nu_protocol::hir::{ Block, Call, ClassifiedCommand, Expression, Pipeline, SpannedExpression, Synthetic, }; -use nu_protocol::{ReturnSuccess, UntaggedValue, Value}; +use nu_protocol::{UntaggedValue, Value}; use nu_source::{Span, Tag}; -use nu_stream::ToActionStream; use nu_stream::{InputStream, OutputStream}; use std::sync::atomic::Ordering; @@ -79,17 +78,15 @@ pub fn run_block( for pipeline in &group.pipelines { match output { Ok(inp) if inp.is_empty() => {} - Ok(inp) => { - let mut output_stream = inp.to_action_stream(); - + Ok(mut output_stream) => { match output_stream.next() { - Some(Ok(ReturnSuccess::Value(Value { + Some(Value { value: UntaggedValue::Error(e), .. - }))) => { + }) => { return Err(e); } - Some(Ok(_item)) => { + Some(_item) => { if let Some(err) = ctx.get_errors().get(0) { ctx.clear_errors(); return Err(err.clone()); @@ -109,9 +106,6 @@ pub fn run_block( return Err(err.clone()); } } - Some(Err(e)) => { - return Err(e); - } } } Err(e) => { diff --git a/crates/nu-engine/src/filesystem/filesystem_shell.rs b/crates/nu-engine/src/filesystem/filesystem_shell.rs index bce9720e26..101316f10c 100644 --- a/crates/nu-engine/src/filesystem/filesystem_shell.rs +++ b/crates/nu-engine/src/filesystem/filesystem_shell.rs @@ -9,7 +9,7 @@ use encoding_rs::Encoding; use nu_data::config::LocalConfigDiff; use nu_protocol::{CommandAction, ConfigPath, TaggedDictBuilder, Value}; use nu_source::{Span, Tag}; -use nu_stream::{ActionStream, Interruptible, ToActionStream}; +use nu_stream::{ActionStream, Interruptible, OutputStream, ToActionStream}; use std::collections::VecDeque; use std::io::{Error, ErrorKind}; use std::path::{Path, PathBuf}; @@ -860,9 +860,9 @@ impl Shell for FilesystemShell { full_path: &Path, save_data: &[u8], name: Span, - ) -> Result { + ) -> Result { match std::fs::write(full_path, save_data) { - Ok(_) => Ok(ActionStream::empty()), + Ok(_) => Ok(OutputStream::empty()), Err(e) => Err(ShellError::labeled_error( e.to_string(), "IO error while saving", diff --git a/crates/nu-engine/src/from_value.rs b/crates/nu-engine/src/from_value.rs index f3a0a7f531..55477706f8 100644 --- a/crates/nu-engine/src/from_value.rs +++ b/crates/nu-engine/src/from_value.rs @@ -166,6 +166,26 @@ impl FromValue for PathBuf { } } +impl FromValue for Tagged { + fn from_value(v: &Value) -> Result { + match v { + Value { + value: UntaggedValue::Primitive(Primitive::String(s)), + tag, + } => Ok(PathBuf::from(s).tagged(tag)), + Value { + value: UntaggedValue::Primitive(Primitive::FilePath(p)), + tag, + } => Ok(p.clone().tagged(tag)), + Value { tag, .. } => Err(ShellError::labeled_error( + "Can't convert to filepath", + "can't convert to filepath", + tag.span, + )), + } + } +} + impl FromValue for ColumnPath { fn from_value(v: &Value) -> Result { match v { diff --git a/crates/nu-engine/src/shell/mod.rs b/crates/nu-engine/src/shell/mod.rs index be4b20a373..c97a9450d8 100644 --- a/crates/nu-engine/src/shell/mod.rs +++ b/crates/nu-engine/src/shell/mod.rs @@ -1,4 +1,4 @@ -use nu_stream::ActionStream; +use nu_stream::{ActionStream, OutputStream}; use crate::command_args::EvaluatedWholeStreamCommandArgs; use crate::maybe_text_codec::StringOrBinary; @@ -49,5 +49,5 @@ pub trait Shell: std::fmt::Debug { path: &Path, contents: &[u8], name: Span, - ) -> Result; + ) -> Result; } diff --git a/crates/nu-engine/src/shell/shell_manager.rs b/crates/nu-engine/src/shell/shell_manager.rs index d0bdf5b427..f07fa7d685 100644 --- a/crates/nu-engine/src/shell/shell_manager.rs +++ b/crates/nu-engine/src/shell/shell_manager.rs @@ -1,7 +1,7 @@ use crate::shell::Shell; use crate::{command_args::EvaluatedWholeStreamCommandArgs, FilesystemShell}; use crate::{filesystem::filesystem_shell::FilesystemShellMode, maybe_text_codec::StringOrBinary}; -use nu_stream::ActionStream; +use nu_stream::{ActionStream, OutputStream}; use crate::shell::shell_args::{CdArgs, CopyArgs, LsArgs, MkdirArgs, MvArgs, RemoveArgs}; use encoding_rs::Encoding; @@ -96,7 +96,7 @@ impl ShellManager { full_path: &Path, save_data: &[u8], name: Span, - ) -> Result { + ) -> Result { self.shells.lock()[self.current_shell()].save(full_path, save_data, name) } diff --git a/crates/nu-engine/src/shell/value_shell.rs b/crates/nu-engine/src/shell/value_shell.rs index 6438ace98b..31b5fca473 100644 --- a/crates/nu-engine/src/shell/value_shell.rs +++ b/crates/nu-engine/src/shell/value_shell.rs @@ -8,7 +8,7 @@ use nu_protocol::ValueStructure; use nu_protocol::{ReturnSuccess, ShellTypeName, UntaggedValue, Value}; use nu_source::SpannedItem; use nu_source::{Span, Tag, Tagged}; -use nu_stream::ActionStream; +use nu_stream::{ActionStream, OutputStream}; use nu_value_ext::ValueExt; use std::collections::VecDeque; use std::ffi::OsStr; @@ -247,7 +247,7 @@ impl Shell for ValueShell { _path: &Path, _contents: &[u8], _name: Span, - ) -> Result { + ) -> Result { Err(ShellError::unimplemented( "save on help shell is not supported", )) diff --git a/crates/nu-errors/src/lib.rs b/crates/nu-errors/src/lib.rs index 1f4fc21f1c..afe9cd64c6 100644 --- a/crates/nu-errors/src/lib.rs +++ b/crates/nu-errors/src/lib.rs @@ -641,7 +641,7 @@ impl ShellError { } pub fn unimplemented(title: impl Into) -> ShellError { - ShellError::unimplemented(&format!("Unimplemented: {}", title.into())) + ShellError::untagged_runtime_error(&format!("Unimplemented: {}", title.into())) } pub fn unexpected(title: impl Into) -> ShellError {