diff --git a/crates/nu-command/src/bytes/add.rs b/crates/nu-command/src/bytes/add.rs index 3a93bc35c7..cc5cbe2e0b 100644 --- a/crates/nu-command/src/bytes/add.rs +++ b/crates/nu-command/src/bytes/add.rs @@ -1,4 +1,4 @@ -use super::{operate, BytesArgument}; +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; @@ -10,12 +10,12 @@ struct Arguments { added_data: Vec, index: Option, end: bool, - column_paths: Option>, + cell_paths: Option>, } -impl BytesArgument for Arguments { - fn take_column_paths(&mut self) -> Option> { - self.column_paths.take() +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() } } @@ -62,12 +62,8 @@ impl Command for BytesAdd { input: PipelineData, ) -> Result { let added_data: Vec = call.req(engine_state, stack, 0)?; - let column_paths: Vec = call.rest(engine_state, stack, 1)?; - let column_paths = if column_paths.is_empty() { - None - } else { - Some(column_paths) - }; + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); let index: Option = call.get_flag(engine_state, stack, "index")?; let end = call.has_flag("end"); @@ -75,7 +71,7 @@ impl Command for BytesAdd { added_data, index, end, - column_paths, + cell_paths, }; operate(add, arg, input, call.head, engine_state.ctrlc.clone()) } @@ -118,7 +114,25 @@ impl Command for BytesAdd { } } -fn add(input: &[u8], args: &Arguments, span: Span) -> Value { +fn add(val: &Value, args: &Arguments, span: Span) -> Value { + match val { + Value::Binary { + val, + span: val_span, + } => add_impl(val, args, *val_span), + other => Value::Error { + error: ShellError::UnsupportedInput( + format!( + "Input's type is {}. This command only works with bytes.", + other.get_type() + ), + span, + ), + }, + } +} + +fn add_impl(input: &[u8], args: &Arguments, span: Span) -> Value { match args.index { None => { if args.end { diff --git a/crates/nu-command/src/bytes/at.rs b/crates/nu-command/src/bytes/at.rs index ee7e4036aa..56ee8870b8 100644 --- a/crates/nu-command/src/bytes/at.rs +++ b/crates/nu-command/src/bytes/at.rs @@ -1,4 +1,4 @@ -use super::{operate, BytesArgument}; +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; @@ -15,12 +15,12 @@ struct Arguments { start: isize, end: isize, arg_span: Span, - column_paths: Option>, + cell_paths: Option>, } -impl BytesArgument for Arguments { - fn take_column_paths(&mut self) -> Option> { - self.column_paths.take() +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() } } @@ -141,17 +141,13 @@ impl Command for BytesAt { ) -> Result { let range: Value = call.req(engine_state, stack, 0)?; let (start, end, arg_span) = parse_range(range, call.head)?; - let column_paths: Vec = call.rest(engine_state, stack, 1)?; - let column_paths = if column_paths.is_empty() { - None - } else { - Some(column_paths) - }; + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); let arg = Arguments { start, end, arg_span, - column_paths, + cell_paths, }; operate(at, arg, input, call.head, engine_state.ctrlc.clone()) } @@ -228,7 +224,25 @@ impl Command for BytesAt { } } -fn at(input: &[u8], arg: &Arguments, span: Span) -> Value { +fn at(val: &Value, args: &Arguments, span: Span) -> Value { + match val { + Value::Binary { + val, + span: val_span, + } => at_impl(val, args, *val_span), + other => Value::Error { + error: ShellError::UnsupportedInput( + format!( + "Input's type is {}. This command only works with bytes.", + other.get_type() + ), + span, + ), + }, + } +} + +fn at_impl(input: &[u8], arg: &Arguments, span: Span) -> Value { let len: isize = input.len() as isize; let start: isize = if arg.start < 0 { diff --git a/crates/nu-command/src/bytes/ends_with.rs b/crates/nu-command/src/bytes/ends_with.rs index 6832c4a056..e372e4fccb 100644 --- a/crates/nu-command/src/bytes/ends_with.rs +++ b/crates/nu-command/src/bytes/ends_with.rs @@ -1,4 +1,4 @@ -use super::{operate, BytesArgument}; +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; @@ -8,12 +8,12 @@ use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShap struct Arguments { pattern: Vec, - column_paths: Option>, + cell_paths: Option>, } -impl BytesArgument for Arguments { - fn take_column_paths(&mut self) -> Option> { - self.column_paths.take() +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() } } @@ -53,15 +53,11 @@ impl Command for BytesEndsWith { input: PipelineData, ) -> Result { let pattern: Vec = call.req(engine_state, stack, 0)?; - let column_paths: Vec = call.rest(engine_state, stack, 1)?; - let column_paths = if column_paths.is_empty() { - None - } else { - Some(column_paths) - }; + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); let arg = Arguments { pattern, - column_paths, + cell_paths, }; operate(ends_with, arg, input, call.head, engine_state.ctrlc.clone()) } @@ -96,10 +92,24 @@ impl Command for BytesEndsWith { } } -fn ends_with(input: &[u8], Arguments { pattern, .. }: &Arguments, span: Span) -> Value { - Value::Bool { - val: input.ends_with(pattern), - span, +fn ends_with(val: &Value, args: &Arguments, span: Span) -> Value { + match val { + Value::Binary { + val, + span: val_span, + } => Value::Bool { + val: val.ends_with(&args.pattern), + span: *val_span, + }, + other => Value::Error { + error: ShellError::UnsupportedInput( + format!( + "Input's type is {}. This command only works with bytes.", + other.get_type() + ), + span, + ), + }, } } diff --git a/crates/nu-command/src/bytes/index_of.rs b/crates/nu-command/src/bytes/index_of.rs index 26c1a55e7f..0840891fef 100644 --- a/crates/nu-command/src/bytes/index_of.rs +++ b/crates/nu-command/src/bytes/index_of.rs @@ -1,4 +1,4 @@ -use super::{operate, BytesArgument}; +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::{Call, CellPath}; use nu_protocol::engine::{Command, EngineState, Stack}; @@ -10,12 +10,12 @@ struct Arguments { pattern: Vec, end: bool, all: bool, - column_paths: Option>, + cell_paths: Option>, } -impl BytesArgument for Arguments { - fn take_column_paths(&mut self) -> Option> { - self.column_paths.take() +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() } } @@ -60,17 +60,13 @@ impl Command for BytesIndexOf { input: PipelineData, ) -> Result { let pattern: Vec = call.req(engine_state, stack, 0)?; - let column_paths: Vec = call.rest(engine_state, stack, 1)?; - let column_paths = if column_paths.is_empty() { - None - } else { - Some(column_paths) - }; + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); let arg = Arguments { pattern, end: call.has_flag("end"), all: call.has_flag("all"), - column_paths, + cell_paths, }; operate(index_of, arg, input, call.head, engine_state.ctrlc.clone()) } @@ -126,7 +122,25 @@ impl Command for BytesIndexOf { } } -fn index_of(input: &[u8], arg: &Arguments, span: Span) -> Value { +fn index_of(val: &Value, args: &Arguments, span: Span) -> Value { + match val { + Value::Binary { + val, + span: val_span, + } => index_of_impl(val, args, *val_span), + other => Value::Error { + error: ShellError::UnsupportedInput( + format!( + "Input's type is {}. This command only works with bytes.", + other.get_type() + ), + span, + ), + }, + } +} + +fn index_of_impl(input: &[u8], arg: &Arguments, span: Span) -> Value { if arg.all { search_all_index(input, &arg.pattern, arg.end, span) } else { diff --git a/crates/nu-command/src/bytes/length.rs b/crates/nu-command/src/bytes/length.rs index 8e7d8a77ce..4f78902a51 100644 --- a/crates/nu-command/src/bytes/length.rs +++ b/crates/nu-command/src/bytes/length.rs @@ -1,4 +1,4 @@ -use super::{operate, BytesArgument}; +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; @@ -10,12 +10,12 @@ use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShap pub struct BytesLen; struct Arguments { - column_paths: Option>, + cell_paths: Option>, } -impl BytesArgument for Arguments { - fn take_column_paths(&mut self) -> Option> { - self.column_paths.take() +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() } } @@ -49,13 +49,9 @@ impl Command for BytesLen { call: &Call, input: PipelineData, ) -> Result { - let column_paths: Vec = call.rest(engine_state, stack, 1)?; - let column_paths = if column_paths.is_empty() { - None - } else { - Some(column_paths) - }; - let arg = Arguments { column_paths }; + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let arg = Arguments { cell_paths }; operate(length, arg, input, call.head, engine_state.ctrlc.clone()) } @@ -78,10 +74,24 @@ impl Command for BytesLen { } } -fn length(input: &[u8], _arg: &Arguments, span: Span) -> Value { - Value::Int { - val: input.len() as i64, - span, +fn length(val: &Value, _args: &Arguments, span: Span) -> Value { + match val { + Value::Binary { + val, + span: val_span, + } => Value::Int { + val: val.len() as i64, + span: *val_span, + }, + other => Value::Error { + error: ShellError::UnsupportedInput( + format!( + "Input's type is {}. This command only works with bytes.", + other.get_type() + ), + span, + ), + }, } } diff --git a/crates/nu-command/src/bytes/mod.rs b/crates/nu-command/src/bytes/mod.rs index a8dca8180f..6d47bb892c 100644 --- a/crates/nu-command/src/bytes/mod.rs +++ b/crates/nu-command/src/bytes/mod.rs @@ -11,11 +11,6 @@ mod replace; mod reverse; mod starts_with; -use nu_protocol::ast::CellPath; -use nu_protocol::{PipelineData, ShellError, Span, Value}; -use std::sync::atomic::AtomicBool; -use std::sync::Arc; - pub use add::BytesAdd; pub use at::BytesAt; pub use build_::BytesBuild; @@ -28,71 +23,3 @@ pub use remove::BytesRemove; pub use replace::BytesReplace; pub use reverse::BytesReverse; pub use starts_with::BytesStartsWith; - -trait BytesArgument { - fn take_column_paths(&mut self) -> Option>; -} - -/// map input pipeline data, for each elements, if it's Binary, invoke relative `cmd` with `arg`. -fn operate( - cmd: C, - mut arg: A, - input: PipelineData, - span: Span, - ctrlc: Option>, -) -> Result -where - A: BytesArgument + Send + Sync + 'static, - C: Fn(&[u8], &A, Span) -> Value + Send + Sync + 'static + Clone + Copy, -{ - match arg.take_column_paths() { - None => input.map( - move |v| match v { - Value::Binary { - val, - span: val_span, - } => cmd(&val, &arg, val_span), - other => Value::Error { - error: ShellError::UnsupportedInput( - format!( - "Input's type is {}. This command only works with bytes.", - other.get_type() - ), - span, - ), - }, - }, - ctrlc, - ), - Some(column_paths) => { - let arg = Arc::new(arg); - input.map( - move |mut v| { - for path in &column_paths { - let opt = arg.clone(); - let r = v.update_cell_path( - &path.members, - Box::new(move |old| { - match old { - Value::Binary {val, span: val_span} => cmd(val, &opt, *val_span), - other => Value::Error { - error: ShellError::UnsupportedInput( - format!( - "Input's type is {}. This command only works with bytes.", - other.get_type() - ), - span, - ), - }}}), - ); - if let Err(error) = r { - return Value::Error { error }; - } - } - v - }, - ctrlc, - ) - } - } -} diff --git a/crates/nu-command/src/bytes/remove.rs b/crates/nu-command/src/bytes/remove.rs index 316d5795a6..f9e4653514 100644 --- a/crates/nu-command/src/bytes/remove.rs +++ b/crates/nu-command/src/bytes/remove.rs @@ -1,4 +1,4 @@ -use super::{operate, BytesArgument}; +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::{ ast::{Call, CellPath}, @@ -9,13 +9,13 @@ use nu_protocol::{ struct Arguments { pattern: Vec, end: bool, - column_paths: Option>, + cell_paths: Option>, all: bool, } -impl BytesArgument for Arguments { - fn take_column_paths(&mut self) -> Option> { - self.column_paths.take() +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() } } @@ -55,12 +55,8 @@ impl Command for BytesRemove { call: &Call, input: PipelineData, ) -> Result { - let column_paths: Vec = call.rest(engine_state, stack, 1)?; - let column_paths = if column_paths.is_empty() { - None - } else { - Some(column_paths) - }; + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); let pattern_to_remove = call.req::>>(engine_state, stack, 0)?; if pattern_to_remove.item.is_empty() { return Err(ShellError::UnsupportedInput( @@ -73,7 +69,7 @@ impl Command for BytesRemove { let arg = Arguments { pattern: pattern_to_remove, end: call.has_flag("end"), - column_paths, + cell_paths, all: call.has_flag("all"), }; @@ -135,7 +131,25 @@ impl Command for BytesRemove { } } -fn remove(input: &[u8], arg: &Arguments, span: Span) -> Value { +fn remove(val: &Value, args: &Arguments, span: Span) -> Value { + match val { + Value::Binary { + val, + span: val_span, + } => remove_impl(val, args, *val_span), + other => Value::Error { + error: ShellError::UnsupportedInput( + format!( + "Input's type is {}. This command only works with bytes.", + other.get_type() + ), + span, + ), + }, + } +} + +fn remove_impl(input: &[u8], arg: &Arguments, span: Span) -> Value { let mut result = vec![]; let remove_all = arg.all; let input_len = input.len(); diff --git a/crates/nu-command/src/bytes/replace.rs b/crates/nu-command/src/bytes/replace.rs index fde42567a2..89e9bab847 100644 --- a/crates/nu-command/src/bytes/replace.rs +++ b/crates/nu-command/src/bytes/replace.rs @@ -1,4 +1,4 @@ -use super::{operate, BytesArgument}; +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::{ ast::{Call, CellPath}, @@ -9,13 +9,13 @@ use nu_protocol::{ struct Arguments { find: Vec, replace: Vec, - column_paths: Option>, + cell_paths: Option>, all: bool, } -impl BytesArgument for Arguments { - fn take_column_paths(&mut self) -> Option> { - self.column_paths.take() +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() } } @@ -55,12 +55,8 @@ impl Command for BytesReplace { call: &Call, input: PipelineData, ) -> Result { - let column_paths: Vec = call.rest(engine_state, stack, 2)?; - let column_paths = if column_paths.is_empty() { - None - } else { - Some(column_paths) - }; + let cell_paths: Vec = call.rest(engine_state, stack, 2)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); let find = call.req::>>(engine_state, stack, 0)?; if find.item.is_empty() { return Err(ShellError::UnsupportedInput( @@ -72,7 +68,7 @@ impl Command for BytesReplace { let arg = Arguments { find: find.item, replace: call.req::>(engine_state, stack, 1)?, - column_paths, + cell_paths, all: call.has_flag("all"), }; @@ -126,7 +122,25 @@ impl Command for BytesReplace { } } -fn replace(input: &[u8], arg: &Arguments, span: Span) -> Value { +fn replace(val: &Value, args: &Arguments, span: Span) -> Value { + match val { + Value::Binary { + val, + span: val_span, + } => replace_impl(val, args, *val_span), + other => Value::Error { + error: ShellError::UnsupportedInput( + format!( + "Input's type is {}. This command only works with bytes.", + other.get_type() + ), + span, + ), + }, + } +} + +fn replace_impl(input: &[u8], arg: &Arguments, span: Span) -> Value { let mut replaced = vec![]; let replace_all = arg.all; diff --git a/crates/nu-command/src/bytes/reverse.rs b/crates/nu-command/src/bytes/reverse.rs index efdfc00dc6..8cbb73916f 100644 --- a/crates/nu-command/src/bytes/reverse.rs +++ b/crates/nu-command/src/bytes/reverse.rs @@ -1,4 +1,4 @@ -use super::{operate, BytesArgument}; +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; @@ -7,12 +7,12 @@ use nu_protocol::Category; use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value}; struct Arguments { - column_paths: Option>, + cell_paths: Option>, } -impl BytesArgument for Arguments { - fn take_column_paths(&mut self) -> Option> { - self.column_paths.take() +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() } } @@ -50,13 +50,9 @@ impl Command for BytesReverse { call: &Call, input: PipelineData, ) -> Result { - let column_paths: Vec = call.rest(engine_state, stack, 0)?; - let column_paths = if column_paths.is_empty() { - None - } else { - Some(column_paths) - }; - let arg = Arguments { column_paths }; + let cell_paths: Vec = call.rest(engine_state, stack, 0)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let arg = Arguments { cell_paths }; operate(reverse, arg, input, call.head, engine_state.ctrlc.clone()) } @@ -82,12 +78,28 @@ impl Command for BytesReverse { } } -fn reverse(input: &[u8], _args: &Arguments, span: Span) -> Value { - let mut reversed_input = input.to_vec(); - reversed_input.reverse(); - Value::Binary { - val: reversed_input, - span, +fn reverse(val: &Value, _args: &Arguments, span: Span) -> Value { + match val { + Value::Binary { + val, + span: val_span, + } => { + let mut reversed_input = val.to_vec(); + reversed_input.reverse(); + Value::Binary { + val: reversed_input, + span: *val_span, + } + } + other => Value::Error { + error: ShellError::UnsupportedInput( + format!( + "Input's type is {}. This command only works with bytes.", + other.get_type() + ), + span, + ), + }, } } diff --git a/crates/nu-command/src/bytes/starts_with.rs b/crates/nu-command/src/bytes/starts_with.rs index a022530a23..c1523e58ed 100644 --- a/crates/nu-command/src/bytes/starts_with.rs +++ b/crates/nu-command/src/bytes/starts_with.rs @@ -1,4 +1,4 @@ -use super::{operate, BytesArgument}; +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; @@ -8,12 +8,12 @@ use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShap struct Arguments { pattern: Vec, - column_paths: Option>, + cell_paths: Option>, } -impl BytesArgument for Arguments { - fn take_column_paths(&mut self) -> Option> { - self.column_paths.take() +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() } } @@ -53,15 +53,11 @@ impl Command for BytesStartsWith { input: PipelineData, ) -> Result { let pattern: Vec = call.req(engine_state, stack, 0)?; - let column_paths: Vec = call.rest(engine_state, stack, 1)?; - let column_paths = if column_paths.is_empty() { - None - } else { - Some(column_paths) - }; + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); let arg = Arguments { pattern, - column_paths, + cell_paths, }; operate( starts_with, @@ -102,10 +98,24 @@ impl Command for BytesStartsWith { } } -fn starts_with(input: &[u8], Arguments { pattern, .. }: &Arguments, span: Span) -> Value { - Value::Bool { - val: input.starts_with(pattern), - span, +fn starts_with(val: &Value, args: &Arguments, span: Span) -> Value { + match val { + Value::Binary { + val, + span: val_span, + } => Value::Bool { + val: val.starts_with(&args.pattern), + span: *val_span, + }, + other => Value::Error { + error: ShellError::UnsupportedInput( + format!( + "Input's type is {}. This command only works with bytes.", + other.get_type() + ), + span, + ), + }, } } diff --git a/crates/nu-command/src/input_handler.rs b/crates/nu-command/src/input_handler.rs new file mode 100644 index 0000000000..ec3f0ca19d --- /dev/null +++ b/crates/nu-command/src/input_handler.rs @@ -0,0 +1,51 @@ +use nu_protocol::ast::CellPath; +use nu_protocol::{PipelineData, ShellError, Span, Value}; +use std::sync::atomic::AtomicBool; +use std::sync::Arc; + +pub trait CmdArgument { + fn take_cell_paths(&mut self) -> Option>; +} + +/// A simple wrapper for `PipelineData::map` method. +/// +/// In detail, for each elements, invoking relative `cmd` with `arg`. +/// +/// If `arg` tell us that it's column path is not None, only map over data under these columns. +/// Else it will apply each column inside a table. +/// +/// The validation of input element should be handle by `cmd` itself. +pub fn operate( + cmd: C, + mut arg: A, + input: PipelineData, + span: Span, + ctrlc: Option>, +) -> Result +where + A: CmdArgument + Send + Sync + 'static, + C: Fn(&Value, &A, Span) -> Value + Send + Sync + 'static + Clone + Copy, +{ + match arg.take_cell_paths() { + None => input.map(move |v| cmd(&v, &arg, v.span().unwrap_or(span)), ctrlc), + Some(column_paths) => { + let arg = Arc::new(arg); + input.map( + move |mut v| { + for path in &column_paths { + let opt = arg.clone(); + let r = v.update_cell_path( + &path.members, + Box::new(move |old| cmd(old, &opt, old.span().unwrap_or(span))), + ); + if let Err(error) = r { + return Value::Error { error }; + } + } + v + }, + ctrlc, + ) + } + } +} diff --git a/crates/nu-command/src/lib.rs b/crates/nu-command/src/lib.rs index b74eb4b1b0..79301ca124 100644 --- a/crates/nu-command/src/lib.rs +++ b/crates/nu-command/src/lib.rs @@ -14,6 +14,7 @@ mod filters; mod formats; mod generators; mod hash; +mod input_handler; mod math; mod misc; mod network; diff --git a/crates/nu-command/src/strings/format/filesize.rs b/crates/nu-command/src/strings/format/filesize.rs index c74a7f0c7a..befef9f45a 100644 --- a/crates/nu-command/src/strings/format/filesize.rs +++ b/crates/nu-command/src/strings/format/filesize.rs @@ -1,11 +1,22 @@ +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; -use nu_protocol::ast::Call; +use nu_protocol::ast::{Call, CellPath}; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{ - format_filesize, Category, Example, IntoPipelineData, PipelineData, PipelineMetadata, - ShellError, Signature, Span, SyntaxShape, Value, + format_filesize, Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, + Value, }; -use std::iter; + +struct Arguments { + format_value: String, + cell_paths: Option>, +} + +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } +} #[derive(Clone)] pub struct FileSize; @@ -17,15 +28,15 @@ impl Command for FileSize { fn signature(&self) -> Signature { Signature::build("format filesize") - .required( - "field", - SyntaxShape::String, - "the name of the column to update", - ) .required( "format value", SyntaxShape::String, - "the format into which convert the filesizes", + "the format into which convert the file sizes", + ) + .rest( + "rest", + SyntaxShape::CellPath, + "optinally find and replace text by column paths", ) .category(Category::Strings) } @@ -45,98 +56,62 @@ impl Command for FileSize { call: &Call, input: PipelineData, ) -> Result { - let field = call.req::(engine_state, stack, 0)?.as_string()?; let format_value = call - .req::(engine_state, stack, 1)? + .req::(engine_state, stack, 0)? .as_string()? .to_ascii_lowercase(); - let span = call.head; - let input_metadata = input.metadata(); - let data_as_value = input.into_value(span); - - // Something need to consider: - // 1. what if input data type is not table? For now just output nothing. - // 2. what if value is not a FileSize type? For now just return nothing too for the value. - match data_as_value { - Value::List { vals, span } => { - format_impl(vals, field, format_value, span, input_metadata) - } - _ => Ok(Value::Nothing { span }.into_pipeline_data()), - } + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let arg = Arguments { + format_value, + cell_paths, + }; + operate( + format_value_impl, + arg, + input, + call.head, + engine_state.ctrlc.clone(), + ) } fn examples(&self) -> Vec { vec![ Example { description: "Convert the size row to KB", - example: "ls | format filesize size KB", + example: "ls | format filesize KB size", result: None, }, Example { description: "Convert the apparent row to B", - example: "du | format filesize apparent B", + example: "du | format filesize B apparent", + result: None, + }, + Example { + description: "Convert the size data to MB", + example: "4Gb | format filesize MB", result: None, }, ] } } -fn format_impl( - vals: Vec, - field: String, - format_value: String, - input_span: Span, - input_metadata: Option, -) -> Result { - let records: Vec = vals - .into_iter() - .map(|rec| { - let record_span = rec.span(); - match rec { - Value::Record { cols, vals, span } => { - let mut new_cols = vec![]; - let mut new_vals = vec![]; - for (c, v) in iter::zip(cols, vals) { - // find column to format, try format the value. - if c == field { - new_vals.push(format_value_impl(v, &format_value, span)); - } else { - new_vals.push(v); - } - new_cols.push(c); - } - Value::Record { - cols: new_cols, - vals: new_vals, - span, - } - } - _ => Value::Nothing { - span: match record_span { - Ok(s) => s, - Err(_) => input_span, - }, - }, - } - }) - .collect(); - - let result = Value::List { - vals: records, - span: input_span, - } - .into_pipeline_data(); - Ok(result.set_metadata(input_metadata)) -} - -fn format_value_impl(val: Value, format_value: &str, span: Span) -> Value { +fn format_value_impl(val: &Value, arg: &Arguments, span: Span) -> Value { match val { Value::Filesize { val, span } => Value::String { // don't need to concern about metric, we just format units by what user input. - val: format_filesize(val, format_value, false), - span, + val: format_filesize(*val, &arg.format_value, false), + span: *span, + }, + other => Value::Error { + error: ShellError::UnsupportedInput( + format!( + "Input's type is not supported, support type: , current_type: {}", + other.get_type() + ), + span, + ), }, - _ => Value::Nothing { span }, } } diff --git a/crates/nu-command/src/strings/str_/case/mod.rs b/crates/nu-command/src/strings/str_/case/mod.rs index fbf7492d33..1211d28294 100644 --- a/crates/nu-command/src/strings/str_/case/mod.rs +++ b/crates/nu-command/src/strings/str_/case/mod.rs @@ -22,10 +22,22 @@ pub use upcase::SubCommand as StrUpcase; use nu_engine::CallExt; +use crate::input_handler::{operate as general_operate, CmdArgument}; use nu_protocol::ast::{Call, CellPath}; use nu_protocol::engine::{EngineState, Stack}; use nu_protocol::{PipelineData, ShellError, Span, Value}; +struct Arguments String + Send + Sync + 'static> { + case_operation: &'static F, + cell_paths: Option>, +} + +impl String + Send + Sync + 'static> CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } +} + pub fn operate( engine_state: &EngineState, stack: &mut Stack, @@ -36,35 +48,20 @@ pub fn operate( where F: Fn(&str) -> String + Send + Sync + 'static, { - let head = call.head; - let column_paths: Vec = call.rest(engine_state, stack, 0)?; - - input.map( - move |v| { - if column_paths.is_empty() { - action(&v, case_operation, head) - } else { - let mut ret = v; - for path in &column_paths { - let r = ret.update_cell_path( - &path.members, - Box::new(move |old| action(old, case_operation, head)), - ); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) + let cell_paths: Vec = call.rest(engine_state, stack, 0)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let args = Arguments { + case_operation, + cell_paths, + }; + general_operate(action, args, input, call.head, engine_state.ctrlc.clone()) } -pub fn action(input: &Value, case_operation: &F, head: Span) -> Value +fn action(input: &Value, args: &Arguments, head: Span) -> Value where F: Fn(&str) -> String + Send + Sync + 'static, { + let case_operation = args.case_operation; match input { Value::String { val, .. } => Value::String { val: case_operation(val), diff --git a/crates/nu-command/src/strings/str_/contains.rs b/crates/nu-command/src/strings/str_/contains.rs index 47e7a93bfe..e835bb8d14 100644 --- a/crates/nu-command/src/strings/str_/contains.rs +++ b/crates/nu-command/src/strings/str_/contains.rs @@ -1,15 +1,27 @@ +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::Category; -use nu_protocol::{ - Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value, -}; +use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value}; #[derive(Clone)] pub struct SubCommand; +struct Arguments { + substring: String, + cell_paths: Option>, + case_insensitive: bool, + not_contain: bool, +} + +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } +} + impl Command for SubCommand { fn name(&self) -> &str { "str contains" @@ -43,7 +55,15 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - operate(engine_state, stack, call, input) + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let args = Arguments { + substring: call.req::(engine_state, stack, 0)?, + cell_paths, + case_insensitive: call.has_flag("insensitive"), + not_contain: call.has_flag("not"), + }; + operate(action, args, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { @@ -175,53 +195,21 @@ impl Command for SubCommand { } } -fn operate( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, -) -> Result { - let head = call.head; - let substring: Spanned = call.req(engine_state, stack, 0)?; - let column_paths: Vec = call.rest(engine_state, stack, 1)?; - let case_insensitive = call.has_flag("insensitive"); - let not_contain = call.has_flag("not"); - - input.map( - move |v| { - if column_paths.is_empty() { - action(&v, case_insensitive, not_contain, &substring.item, head) - } else { - let mut ret = v; - for path in &column_paths { - let p = substring.item.clone(); - let r = ret.update_cell_path( - &path.members, - Box::new(move |old| action(old, case_insensitive, not_contain, &p, head)), - ); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) -} - fn action( input: &Value, - case_insensitive: bool, - not_contain: bool, - substring: &str, + Arguments { + case_insensitive, + not_contain, + substring, + .. + }: &Arguments, head: Span, ) -> Value { match input { Value::String { val, .. } => Value::Bool { val: match case_insensitive { true => { - if not_contain { + if *not_contain { !val.to_lowercase() .contains(substring.to_lowercase().as_str()) } else { @@ -230,7 +218,7 @@ fn action( } } false => { - if not_contain { + if *not_contain { !val.contains(substring) } else { val.contains(substring) diff --git a/crates/nu-command/src/strings/str_/distance.rs b/crates/nu-command/src/strings/str_/distance.rs index a2d940b4e5..a15a4ff765 100644 --- a/crates/nu-command/src/strings/str_/distance.rs +++ b/crates/nu-command/src/strings/str_/distance.rs @@ -1,14 +1,26 @@ +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::{ ast::{Call, CellPath}, engine::{Command, EngineState, Stack}, - levenshtein_distance, Category, Example, PipelineData, ShellError, Signature, Span, Spanned, + levenshtein_distance, Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, }; #[derive(Clone)] pub struct SubCommand; +struct Arguments { + compare_string: String, + cell_paths: Option>, +} + +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } +} + impl Command for SubCommand { fn name(&self) -> &str { "str distance" @@ -44,7 +56,14 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - operate(engine_state, stack, call, input) + let compare_string: String = call.req(engine_state, stack, 0)?; + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let args = Arguments { + compare_string, + cell_paths, + }; + operate(action, args, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { @@ -63,40 +82,8 @@ impl Command for SubCommand { } } -fn operate( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, -) -> Result { - let head = call.head; - let compare_string: Spanned = call.req(engine_state, stack, 0)?; - let column_paths: Vec = call.rest(engine_state, stack, 1)?; - - input.map( - move |v| { - if column_paths.is_empty() { - action(&v, &compare_string.item, head) - } else { - let mut ret = v; - for path in &column_paths { - let c = compare_string.item.clone(); - let r = ret.update_cell_path( - &path.members, - Box::new(move |old| action(old, &c, head)), - ); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) -} - -fn action(input: &Value, compare_string: &str, head: Span) -> Value { +fn action(input: &Value, args: &Arguments, head: Span) -> Value { + let compare_string = &args.compare_string; match &input { Value::String { val, .. } => { let distance = levenshtein_distance(val, compare_string); diff --git a/crates/nu-command/src/strings/str_/ends_with.rs b/crates/nu-command/src/strings/str_/ends_with.rs index 1805ad0139..ccb5f51e80 100644 --- a/crates/nu-command/src/strings/str_/ends_with.rs +++ b/crates/nu-command/src/strings/str_/ends_with.rs @@ -1,11 +1,22 @@ +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::Category; -use nu_protocol::Spanned; use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value}; +struct Arguments { + substring: String, + cell_paths: Option>, +} + +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } +} + #[derive(Clone)] pub struct SubCommand; @@ -40,7 +51,13 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - operate(engine_state, stack, call, input) + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let args = Arguments { + substring: call.req::(engine_state, stack, 0)?, + cell_paths, + }; + operate(action, args, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { @@ -65,43 +82,10 @@ impl Command for SubCommand { } } -fn operate( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, -) -> Result { - let head = call.head; - let substring: Spanned = call.req(engine_state, stack, 0)?; - let column_paths: Vec = call.rest(engine_state, stack, 1)?; - - input.map( - move |v| { - if column_paths.is_empty() { - action(&v, &substring.item, head) - } else { - let mut ret = v; - for path in &column_paths { - let p = substring.item.clone(); - let r = ret.update_cell_path( - &path.members, - Box::new(move |old| action(old, &p, head)), - ); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) -} - -fn action(input: &Value, substring: &str, head: Span) -> Value { +fn action(input: &Value, args: &Arguments, head: Span) -> Value { match input { Value::String { val, .. } => Value::Bool { - val: val.ends_with(substring), + val: val.ends_with(&args.substring), span: head, }, other => Value::Error { diff --git a/crates/nu-command/src/strings/str_/index_of.rs b/crates/nu-command/src/strings/str_/index_of.rs index c68cf3ba6e..b621fbc0d5 100644 --- a/crates/nu-command/src/strings/str_/index_of.rs +++ b/crates/nu-command/src/strings/str_/index_of.rs @@ -1,3 +1,4 @@ +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; @@ -5,13 +6,18 @@ use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::Category; use nu_protocol::Spanned; use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value}; -use std::sync::Arc; struct Arguments { end: bool, substring: String, range: Option, - column_paths: Vec, + cell_paths: Option>, +} + +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } } #[derive(Clone)] @@ -58,7 +64,16 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - operate(engine_state, stack, call, input) + let substring: Spanned = call.req(engine_state, stack, 0)?; + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let args = Arguments { + substring: substring.item, + range: call.get_flag(engine_state, stack, "range")?, + end: call.has_flag("end"), + cell_paths, + }; + operate(action, args, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { @@ -97,44 +112,6 @@ impl Command for SubCommand { } } -fn operate( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, -) -> Result { - let substring: Spanned = call.req(engine_state, stack, 0)?; - - let options = Arc::new(Arguments { - substring: substring.item, - range: call.get_flag(engine_state, stack, "range")?, - end: call.has_flag("end"), - column_paths: call.rest(engine_state, stack, 1)?, - }); - let head = call.head; - input.map( - move |v| { - if options.column_paths.is_empty() { - action(&v, &options, head) - } else { - let mut ret = v; - for path in &options.column_paths { - let opt = options.clone(); - let r = ret.update_cell_path( - &path.members, - Box::new(move |old| action(old, &opt, head)), - ); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) -} - fn action( input: &Value, Arguments { @@ -294,7 +271,7 @@ mod tests { val: String::from(""), span: Span::test_data(), }), - column_paths: vec![], + cell_paths: None, end: false, }; @@ -316,7 +293,7 @@ mod tests { val: String::from(""), span: Span::test_data(), }), - column_paths: vec![], + cell_paths: None, end: false, }; @@ -339,7 +316,7 @@ mod tests { val: String::from("1"), span: Span::test_data(), }), - column_paths: vec![], + cell_paths: None, end: false, }; @@ -361,7 +338,7 @@ mod tests { val: String::from(",5"), span: Span::test_data(), }), - column_paths: vec![], + cell_paths: None, end: false, }; @@ -383,7 +360,7 @@ mod tests { val: String::from("2,6"), span: Span::test_data(), }), - column_paths: vec![], + cell_paths: None, end: false, }; @@ -405,7 +382,7 @@ mod tests { val: String::from("2,4"), span: Span::test_data(), }), - column_paths: vec![], + cell_paths: None, end: false, }; diff --git a/crates/nu-command/src/strings/str_/length.rs b/crates/nu-command/src/strings/str_/length.rs index ec7330305e..2e99fed27f 100644 --- a/crates/nu-command/src/strings/str_/length.rs +++ b/crates/nu-command/src/strings/str_/length.rs @@ -1,13 +1,23 @@ +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::Category; use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value}; - #[derive(Clone)] pub struct SubCommand; +struct Arguments { + cell_paths: Option>, +} + +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } +} + impl Command for SubCommand { fn name(&self) -> &str { "str length" @@ -38,7 +48,10 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - operate(engine_state, stack, call, input) + let cell_paths: Vec = call.rest(engine_state, stack, 0)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let args = Arguments { cell_paths }; + operate(action, args, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { @@ -60,35 +73,7 @@ impl Command for SubCommand { } } -fn operate( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, -) -> Result { - let head = call.head; - let column_paths: Vec = call.rest(engine_state, stack, 0)?; - input.map( - move |v| { - if column_paths.is_empty() { - action(&v, head) - } else { - let mut ret = v; - for path in &column_paths { - let r = - ret.update_cell_path(&path.members, Box::new(move |old| action(old, head))); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) -} - -fn action(input: &Value, head: Span) -> Value { +fn action(input: &Value, _arg: &Arguments, head: Span) -> Value { match input { Value::String { val, .. } => Value::Int { val: val.len() as i64, diff --git a/crates/nu-command/src/strings/str_/lpad.rs b/crates/nu-command/src/strings/str_/lpad.rs index 026fb55255..c89a3074c0 100644 --- a/crates/nu-command/src/strings/str_/lpad.rs +++ b/crates/nu-command/src/strings/str_/lpad.rs @@ -1,15 +1,21 @@ +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::Category; use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value}; -use std::sync::Arc; struct Arguments { length: Option, character: Option, - column_paths: Vec, + cell_paths: Option>, +} + +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } } #[derive(Clone)] @@ -52,7 +58,21 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - operate(engine_state, stack, call, input) + let cell_paths: Vec = call.rest(engine_state, stack, 0)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let args = Arguments { + length: call.get_flag(engine_state, stack, "length")?, + character: call.get_flag(engine_state, stack, "character")?, + cell_paths, + }; + + if args.length.expect("this exists") < 0 { + return Err(ShellError::UnsupportedInput( + String::from("The length of the string cannot be negative"), + call.head, + )); + } + operate(action, args, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { @@ -93,49 +113,6 @@ impl Command for SubCommand { } } -fn operate( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, -) -> Result { - let options = Arc::new(Arguments { - length: call.get_flag(engine_state, stack, "length")?, - character: call.get_flag(engine_state, stack, "character")?, - column_paths: call.rest(engine_state, stack, 0)?, - }); - - if options.length.expect("this exists") < 0 { - return Err(ShellError::UnsupportedInput( - String::from("The length of the string cannot be negative"), - call.head, - )); - } - - let head = call.head; - input.map( - move |v| { - if options.column_paths.is_empty() { - action(&v, &options, head) - } else { - let mut ret = v; - for path in &options.column_paths { - let opt = options.clone(); - let r = ret.update_cell_path( - &path.members, - Box::new(move |old| action(old, &opt, head)), - ); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) -} - fn action( input: &Value, Arguments { diff --git a/crates/nu-command/src/strings/str_/replace.rs b/crates/nu-command/src/strings/str_/replace.rs index a3d300b3c3..15cd243af5 100644 --- a/crates/nu-command/src/strings/str_/replace.rs +++ b/crates/nu-command/src/strings/str_/replace.rs @@ -1,3 +1,4 @@ +use crate::input_handler::{operate, CmdArgument}; use fancy_regex::{NoExpand, Regex}; use nu_engine::CallExt; use nu_protocol::{ @@ -5,17 +6,22 @@ use nu_protocol::{ engine::{Command, EngineState, Stack}, Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value, }; -use std::sync::Arc; struct Arguments { all: bool, find: Spanned, replace: Spanned, - column_paths: Vec, + cell_paths: Option>, literal_replace: bool, no_regex: bool, } +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } +} + #[derive(Clone)] pub struct SubCommand; @@ -62,7 +68,22 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - operate(engine_state, stack, call, input) + let find: Spanned = call.req(engine_state, stack, 0)?; + let replace: Spanned = call.req(engine_state, stack, 1)?; + let cell_paths: Vec = call.rest(engine_state, stack, 2)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let literal_replace = call.has_flag("no-expand"); + let no_regex = call.has_flag("string"); + + let args = Arguments { + all: call.has_flag("all"), + find, + replace, + cell_paths, + literal_replace, + no_regex, + }; + operate(action, args, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { @@ -154,50 +175,6 @@ impl Command for SubCommand { } } -fn operate( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, -) -> Result { - let head = call.head; - let find: Spanned = call.req(engine_state, stack, 0)?; - let replace: Spanned = call.req(engine_state, stack, 1)?; - let literal_replace = call.has_flag("no-expand"); - let no_regex = call.has_flag("string"); - - let options = Arc::new(Arguments { - all: call.has_flag("all"), - find, - replace, - column_paths: call.rest(engine_state, stack, 2)?, - literal_replace, - no_regex, - }); - - input.map( - move |v| { - if options.column_paths.is_empty() { - action(&v, &options, head) - } else { - let mut ret = v; - for path in &options.column_paths { - let opt = options.clone(); - let r = ret.update_cell_path( - &path.members, - Box::new(move |old| action(old, &opt, head)), - ); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) -} - struct FindReplace<'a>(&'a str, &'a str); fn action( @@ -305,7 +282,7 @@ mod tests { let options = Arguments { find: test_spanned_string("Cargo.(.+)"), replace: test_spanned_string("Carga.$1"), - column_paths: vec![], + cell_paths: None, literal_replace: false, all: false, no_regex: false, diff --git a/crates/nu-command/src/strings/str_/reverse.rs b/crates/nu-command/src/strings/str_/reverse.rs index 2fa4987321..abc21894e7 100644 --- a/crates/nu-command/src/strings/str_/reverse.rs +++ b/crates/nu-command/src/strings/str_/reverse.rs @@ -1,3 +1,4 @@ +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; @@ -8,6 +9,16 @@ use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShap #[derive(Clone)] pub struct SubCommand; +struct Arguments { + cell_paths: Option>, +} + +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } +} + impl Command for SubCommand { fn name(&self) -> &str { "str reverse" @@ -38,7 +49,10 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - operate(engine_state, stack, call, input) + let cell_paths: Vec = call.rest(engine_state, stack, 0)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let args = Arguments { cell_paths }; + operate(action, args, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { @@ -76,35 +90,7 @@ impl Command for SubCommand { } } -fn operate( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, -) -> Result { - let head = call.head; - let column_paths: Vec = call.rest(engine_state, stack, 0)?; - input.map( - move |v| { - if column_paths.is_empty() { - action(&v, head) - } else { - let mut ret = v; - for path in &column_paths { - let r = - ret.update_cell_path(&path.members, Box::new(move |old| action(old, head))); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) -} - -fn action(input: &Value, head: Span) -> Value { +fn action(input: &Value, _arg: &Arguments, head: Span) -> Value { match input { Value::String { val, .. } => Value::String { val: val.chars().rev().collect::(), diff --git a/crates/nu-command/src/strings/str_/rpad.rs b/crates/nu-command/src/strings/str_/rpad.rs index 2e9f5e463d..e2ffd22890 100644 --- a/crates/nu-command/src/strings/str_/rpad.rs +++ b/crates/nu-command/src/strings/str_/rpad.rs @@ -1,15 +1,21 @@ +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::Category; use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value}; -use std::sync::Arc; struct Arguments { length: Option, character: Option, - column_paths: Vec, + cell_paths: Option>, +} + +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } } #[derive(Clone)] @@ -52,7 +58,21 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - operate(engine_state, stack, call, input) + let cell_paths: Vec = call.rest(engine_state, stack, 0)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let args = Arguments { + length: call.get_flag(engine_state, stack, "length")?, + character: call.get_flag(engine_state, stack, "character")?, + cell_paths, + }; + + if args.length.expect("this exists") < 0 { + return Err(ShellError::UnsupportedInput( + String::from("The length of the string cannot be negative"), + call.head, + )); + } + operate(action, args, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { @@ -93,49 +113,6 @@ impl Command for SubCommand { } } -fn operate( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, -) -> Result { - let options = Arc::new(Arguments { - length: call.get_flag(engine_state, stack, "length")?, - character: call.get_flag(engine_state, stack, "character")?, - column_paths: call.rest(engine_state, stack, 0)?, - }); - - if options.length.expect("this exists") < 0 { - return Err(ShellError::UnsupportedInput( - String::from("The length of the string cannot be negative"), - call.head, - )); - } - - let head = call.head; - input.map( - move |v| { - if options.column_paths.is_empty() { - action(&v, &options, head) - } else { - let mut ret = v; - for path in &options.column_paths { - let opt = options.clone(); - let r = ret.update_cell_path( - &path.members, - Box::new(move |old| action(old, &opt, head)), - ); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) -} - fn action( input: &Value, Arguments { diff --git a/crates/nu-command/src/strings/str_/starts_with.rs b/crates/nu-command/src/strings/str_/starts_with.rs index 50aa46e8f9..9639169053 100644 --- a/crates/nu-command/src/strings/str_/starts_with.rs +++ b/crates/nu-command/src/strings/str_/starts_with.rs @@ -1,3 +1,4 @@ +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; @@ -5,11 +6,16 @@ use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::Category; use nu_protocol::Spanned; use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value}; -use std::sync::Arc; struct Arguments { substring: String, - column_paths: Vec, + cell_paths: Option>, +} + +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } } #[derive(Clone)] @@ -47,7 +53,14 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - operate(engine_state, stack, call, input) + let substring: Spanned = call.req(engine_state, stack, 0)?; + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let args = Arguments { + substring: substring.item, + cell_paths, + }; + operate(action, args, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { @@ -80,42 +93,6 @@ impl Command for SubCommand { } } -fn operate( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, -) -> Result { - let substring: Spanned = call.req(engine_state, stack, 0)?; - - let options = Arc::new(Arguments { - substring: substring.item, - column_paths: call.rest(engine_state, stack, 1)?, - }); - let head = call.head; - input.map( - move |v| { - if options.column_paths.is_empty() { - action(&v, &options, head) - } else { - let mut ret = v; - for path in &options.column_paths { - let opt = options.clone(); - let r = ret.update_cell_path( - &path.members, - Box::new(move |old| action(old, &opt, head)), - ); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) -} - fn action(input: &Value, Arguments { substring, .. }: &Arguments, head: Span) -> Value { match input { Value::String { val: s, .. } => { diff --git a/crates/nu-command/src/strings/str_/substring.rs b/crates/nu-command/src/strings/str_/substring.rs index b22a98eac2..0214510661 100644 --- a/crates/nu-command/src/strings/str_/substring.rs +++ b/crates/nu-command/src/strings/str_/substring.rs @@ -1,17 +1,23 @@ +use crate::input_handler::{operate, CmdArgument}; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::ast::CellPath; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value}; use std::cmp::Ordering; -use std::sync::Arc; #[derive(Clone)] pub struct SubCommand; struct Arguments { - range: Value, - column_paths: Vec, + indexes: Substring, + cell_paths: Option>, +} + +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } } #[derive(Clone)] @@ -59,7 +65,15 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - operate(engine_state, stack, call, input) + let range = call.req(engine_state, stack, 0)?; + let indexes: Substring = process_arguments(&range, call.head)?.into(); + let cell_paths: Vec = call.rest(engine_state, stack, 1)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let args = Arguments { + indexes, + cell_paths, + }; + operate(action, args, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { @@ -99,44 +113,8 @@ impl Command for SubCommand { } } -fn operate( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, -) -> Result { - let options = Arc::new(Arguments { - range: call.req(engine_state, stack, 0)?, - column_paths: call.rest(engine_state, stack, 1)?, - }); - - let head = call.head; - let indexes: Arc = Arc::new(process_arguments(&options, head)?.into()); - - input.map( - move |v| { - if options.column_paths.is_empty() { - action(&v, &indexes, head) - } else { - let mut ret = v; - for path in &options.column_paths { - let indexes = indexes.clone(); - let r = ret.update_cell_path( - &path.members, - Box::new(move |old| action(old, &indexes, head)), - ); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) -} - -fn action(input: &Value, options: &Substring, head: Span) -> Value { +fn action(input: &Value, args: &Arguments, head: Span) -> Value { + let options = &args.indexes; match input { Value::String { val: s, .. } => { let len: isize = s.len() as isize; @@ -203,8 +181,8 @@ fn action(input: &Value, options: &Substring, head: Span) -> Value { } } -fn process_arguments(options: &Arguments, head: Span) -> Result<(isize, isize), ShellError> { - let search = match &options.range { +fn process_arguments(range: &Value, head: Span) -> Result<(isize, isize), ShellError> { + let search = match range { Value::Range { val, .. } => { let start = val.from()?; let end = val.to()?; @@ -357,7 +335,14 @@ mod tests { for expectation in &cases { let expected = expectation.expected; - let actual = action(&word, &expectation.options(), Span::test_data()); + let actual = action( + &word, + &super::Arguments { + indexes: expectation.options(), + cell_paths: None, + }, + Span::test_data(), + ); assert_eq!( actual, diff --git a/crates/nu-command/src/strings/str_/trim/trim_.rs b/crates/nu-command/src/strings/str_/trim/trim_.rs index 4f6dc2c6e8..da1feac888 100644 --- a/crates/nu-command/src/strings/str_/trim/trim_.rs +++ b/crates/nu-command/src/strings/str_/trim/trim_.rs @@ -1,3 +1,4 @@ +use crate::input_handler::{operate, CmdArgument}; use fancy_regex::Regex; use nu_engine::CallExt; use nu_protocol::{ @@ -10,8 +11,16 @@ use nu_protocol::{ pub struct SubCommand; struct Arguments { - character: Option>, - column_paths: Vec, + to_trim: Option, + closure_flags: ClosureFlags, + cell_paths: Option>, + mode: ActionMode, +} + +impl CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } } #[derive(Default, Debug, Copy, Clone)] @@ -74,7 +83,45 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - operate(engine_state, stack, call, input, &trim) + let character = call.get_flag::>(engine_state, stack, "char")?; + let to_trim = match character.as_ref() { + Some(v) => { + if v.item.chars().count() > 1 { + return Err(ShellError::GenericError( + "Trim only works with single character".into(), + "needs single character".into(), + Some(v.span), + None, + Vec::new(), + )); + } + v.item.chars().next() + } + None => None, + }; + let cell_paths: Vec = call.rest(engine_state, stack, 0)?; + let cell_paths = (!cell_paths.is_empty()).then(|| cell_paths); + let mode = match cell_paths { + None => ActionMode::Global, + Some(_) => ActionMode::Local, + }; + let args = Arguments { + to_trim, + closure_flags: ClosureFlags { + all_flag: call.has_flag("all"), + left_trim: call.has_flag("left"), + right_trim: call.has_flag("right"), + format_flag: call.has_flag("format"), + both_flag: call.has_flag("both") + || (!call.has_flag("all") + && !call.has_flag("left") + && !call.has_flag("right") + && !call.has_flag("format")), // this is the case if no flags are provided + }, + cell_paths, + mode, + }; + operate(action, args, input, call.head, engine_state.ctrlc.clone()) } fn examples(&self) -> Vec { @@ -118,118 +165,25 @@ impl Command for SubCommand { } } -pub fn operate( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, - trim_operation: &'static F, -) -> Result -where - F: Fn(&str, Option, &ClosureFlags) -> String + Send + Sync + 'static, -{ - let head = call.head; - let (options, closure_flags, input) = ( - Arguments { - character: call.get_flag(engine_state, stack, "char")?, - column_paths: call.rest(engine_state, stack, 0)?, - }, - ClosureFlags { - all_flag: call.has_flag("all"), - left_trim: call.has_flag("left"), - right_trim: call.has_flag("right"), - format_flag: call.has_flag("format"), - both_flag: call.has_flag("both") - || (!call.has_flag("all") - && !call.has_flag("left") - && !call.has_flag("right") - && !call.has_flag("format")), // this is the case if no flags are provided - }, - input, - ); - let to_trim = match options.character.as_ref() { - Some(v) => { - if v.item.chars().count() > 1 { - return Err(ShellError::GenericError( - "Trim only works with single character".into(), - "needs single character".into(), - Some(v.span), - None, - Vec::new(), - )); - } - v.item.chars().next() - } - None => None, - }; - - input.map( - move |v| { - if options.column_paths.is_empty() { - action( - &v, - head, - to_trim, - &closure_flags, - &trim_operation, - ActionMode::Global, - ) - } else { - let mut ret = v; - for path in &options.column_paths { - let r = ret.update_cell_path( - &path.members, - Box::new(move |old| { - action( - old, - head, - to_trim, - &closure_flags, - &trim_operation, - ActionMode::Local, - ) - }), - ); - if let Err(error) = r { - return Value::Error { error }; - } - } - ret - } - }, - engine_state.ctrlc.clone(), - ) -} - #[derive(Debug, Copy, Clone)] pub enum ActionMode { Local, Global, } -pub fn action( - input: &Value, - head: Span, - char_: Option, - closure_flags: &ClosureFlags, - trim_operation: &F, - mode: ActionMode, -) -> Value -where - F: Fn(&str, Option, &ClosureFlags) -> String + Send + Sync + 'static, -{ +fn action(input: &Value, arg: &Arguments, head: Span) -> Value { + let char_ = arg.to_trim; + let closure_flags = &arg.closure_flags; + let mode = &arg.mode; match input { Value::String { val: s, .. } => Value::String { - val: trim_operation(s, char_, closure_flags), + val: trim(s, char_, closure_flags), span: head, }, other => match mode { ActionMode::Global => match other { Value::Record { cols, vals, span } => { - let new_vals = vals - .iter() - .map(|v| action(v, head, char_, closure_flags, trim_operation, mode)) - .collect(); + let new_vals = vals.iter().map(|v| action(v, arg, head)).collect(); Value::Record { cols: cols.to_vec(), @@ -238,10 +192,7 @@ where } } Value::List { vals, span } => { - let new_vals = vals - .iter() - .map(|v| action(v, head, char_, closure_flags, trim_operation, mode)) - .collect(); + let new_vals = vals.iter().map(|v| action(v, arg, head)).collect(); Value::List { vals: new_vals, @@ -374,14 +325,13 @@ mod tests { ..Default::default() }; - let actual = action( - &word, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Local, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Local, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -393,15 +343,13 @@ mod tests { both_flag: true, ..Default::default() }; - - let actual = action( - &word, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -413,15 +361,14 @@ mod tests { both_flag: true, ..Default::default() }; + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; - let actual = action( - &number, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let actual = action(&number, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -435,14 +382,13 @@ mod tests { ..Default::default() }; - let actual = action( - &row, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&row, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -455,14 +401,13 @@ mod tests { ..Default::default() }; - let actual = action( - &row, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&row, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -475,14 +420,13 @@ mod tests { ..Default::default() }; - let actual = action( - &word, - Span::test_data(), - Some('!'), - &closure_flags, - &trim, - ActionMode::Local, - ); + let args = Arguments { + to_trim: Some('!'), + closure_flags, + cell_paths: None, + mode: ActionMode::Local, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } #[test] @@ -494,14 +438,13 @@ mod tests { ..Default::default() }; - let actual = action( - &word, - Span::test_data(), - Some(' '), - &closure_flags, - &trim, - ActionMode::Local, - ); + let args = Arguments { + to_trim: Some(' '), + closure_flags, + cell_paths: None, + mode: ActionMode::Local, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -517,15 +460,13 @@ mod tests { all_flag: true, ..Default::default() }; - - let actual = action( - &row, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&row, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -571,14 +512,13 @@ mod tests { ..Default::default() }; - let actual = action( - &row, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&row, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -591,14 +531,13 @@ mod tests { ..Default::default() }; - let actual = action( - &word, - Span::test_data(), - Some('.'), - &closure_flags, - &trim, - ActionMode::Local, - ); + let args = Arguments { + to_trim: Some('.'), + closure_flags, + cell_paths: None, + mode: ActionMode::Local, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -611,14 +550,13 @@ mod tests { ..Default::default() }; - let actual = action( - &row, - Span::test_data(), - Some('!'), - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: Some('!'), + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&row, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -664,14 +602,13 @@ mod tests { ..Default::default() }; - let actual = action( - &row, - Span::test_data(), - Some('#'), - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: Some('#'), + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&row, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -684,14 +621,13 @@ mod tests { ..Default::default() }; - let actual = action( - &word, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Local, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Local, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -704,14 +640,13 @@ mod tests { ..Default::default() }; - let actual = action( - &number, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&number, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -724,14 +659,13 @@ mod tests { ..Default::default() }; - let actual = action( - &word, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -744,14 +678,13 @@ mod tests { ..Default::default() }; - let actual = action( - &row, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&row, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -796,15 +729,13 @@ mod tests { left_trim: true, ..Default::default() }; - - let actual = action( - &row, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&row, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -817,14 +748,13 @@ mod tests { ..Default::default() }; - let actual = action( - &word, - Span::test_data(), - Some('!'), - &closure_flags, - &trim, - ActionMode::Local, - ); + let args = Arguments { + to_trim: Some('!'), + closure_flags, + cell_paths: None, + mode: ActionMode::Local, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } #[test] @@ -835,15 +765,13 @@ mod tests { right_trim: true, ..Default::default() }; - - let actual = action( - &word, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Local, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Local, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -855,15 +783,13 @@ mod tests { right_trim: true, ..Default::default() }; - - let actual = action( - &word, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -876,14 +802,13 @@ mod tests { ..Default::default() }; - let actual = action( - &number, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&number, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -896,14 +821,13 @@ mod tests { ..Default::default() }; - let actual = action( - &row, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&row, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -949,14 +873,13 @@ mod tests { ..Default::default() }; - let actual = action( - &row, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&row, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -969,14 +892,13 @@ mod tests { ..Default::default() }; - let actual = action( - &word, - Span::test_data(), - Some('#'), - &closure_flags, - &trim, - ActionMode::Local, - ); + let args = Arguments { + to_trim: Some('#'), + closure_flags, + cell_paths: None, + mode: ActionMode::Local, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -989,14 +911,13 @@ mod tests { ..Default::default() }; - let actual = action( - &word, - Span::test_data(), - Some(' '), - &closure_flags, - &trim, - ActionMode::Local, - ); + let args = Arguments { + to_trim: Some(' '), + closure_flags, + cell_paths: None, + mode: ActionMode::Local, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -1008,15 +929,13 @@ mod tests { format_flag: true, ..Default::default() }; - - let actual = action( - &word, - Span::test_data(), - Some(' '), - &closure_flags, - &trim, - ActionMode::Local, - ); + let args = Arguments { + to_trim: Some(' '), + closure_flags, + cell_paths: None, + mode: ActionMode::Local, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } #[test] @@ -1028,14 +947,13 @@ mod tests { ..Default::default() }; - let actual = action( - &number, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&number, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -1048,14 +966,13 @@ mod tests { ..Default::default() }; - let actual = action( - &row, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&row, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -1101,14 +1018,13 @@ mod tests { ..Default::default() }; - let actual = action( - &row, - Span::test_data(), - None, - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: None, + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&row, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -1121,14 +1037,13 @@ mod tests { ..Default::default() }; - let actual = action( - &word, - Span::test_data(), - Some('.'), - &closure_flags, - &trim, - ActionMode::Local, - ); + let args = Arguments { + to_trim: Some('.'), + closure_flags, + cell_paths: None, + mode: ActionMode::Local, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -1142,14 +1057,13 @@ mod tests { ..Default::default() }; - let actual = action( - &word, - Span::test_data(), - Some(' '), - &closure_flags, - &trim, - ActionMode::Local, - ); + let args = Arguments { + to_trim: Some(' '), + closure_flags, + cell_paths: None, + mode: ActionMode::Local, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } @@ -1163,14 +1077,13 @@ mod tests { ..Default::default() }; - let actual = action( - &word, - Span::test_data(), - Some(' '), - &closure_flags, - &trim, - ActionMode::Global, - ); + let args = Arguments { + to_trim: Some(' '), + closure_flags, + cell_paths: None, + mode: ActionMode::Global, + }; + let actual = action(&word, &args, Span::test_data()); assert_eq!(actual, expected); } } diff --git a/crates/nu-command/tests/commands/format.rs b/crates/nu-command/tests/commands/format.rs index d3b585ecf8..4cbd43346e 100644 --- a/crates/nu-command/tests/commands/format.rs +++ b/crates/nu-command/tests/commands/format.rs @@ -55,7 +55,7 @@ fn format_filesize_works() { cwd: dirs.test(), pipeline( r#" ls - | format filesize size KB + | format filesize KB size | get size | first "# @@ -80,7 +80,7 @@ fn format_filesize_works_with_nonempty_files() { let actual = nu!( cwd: dirs.test(), - "ls sample.toml | format filesize size B | get size | first" + "ls sample.toml | format filesize B size | get size | first" ); #[cfg(not(windows))]