diff --git a/crates/nu-command/src/commands/filters/drop/mod.rs b/crates/nu-command/src/commands/filters/drop/mod.rs index 428affff8f..407d1c1006 100644 --- a/crates/nu-command/src/commands/filters/drop/mod.rs +++ b/crates/nu-command/src/commands/filters/drop/mod.rs @@ -1,5 +1,7 @@ mod column; mod command; +mod nth; pub use column::SubCommand as DropColumn; pub use command::Command as Drop; +pub use nth::SubCommand as DropNth; diff --git a/crates/nu-command/src/commands/filters/drop/nth.rs b/crates/nu-command/src/commands/filters/drop/nth.rs new file mode 100644 index 0000000000..2208751703 --- /dev/null +++ b/crates/nu-command/src/commands/filters/drop/nth.rs @@ -0,0 +1,91 @@ +use crate::prelude::*; +use nu_engine::WholeStreamCommand; +use nu_errors::ShellError; +use nu_protocol::{Signature, SyntaxShape, Value}; +use nu_source::Tagged; + +pub struct SubCommand; + +impl WholeStreamCommand for SubCommand { + fn name(&self) -> &str { + "drop nth" + } + + fn signature(&self) -> Signature { + Signature::build("drop nth") + .required( + "row number", + SyntaxShape::Int, + "the number of the row to drop", + ) + .rest(SyntaxShape::Any, "Optionally drop more rows") + } + + fn usage(&self) -> &str { + "Drops the selected rows." + } + + fn run(&self, args: CommandArgs) -> Result { + drop(args) + } + + fn examples(&self) -> Vec { + vec![ + Example { + description: "Drop the second row", + example: "echo [first second third] | drop nth 1", + result: Some(vec![Value::from("first"), Value::from("third")]), + }, + Example { + description: "Drop the first and third rows", + example: "echo [first second third] | drop nth 0 2", + result: Some(vec![Value::from("second")]), + }, + ] + } +} + +fn drop(args: CommandArgs) -> Result { + let row_number: Tagged = args.req(0)?; + let and_rows: Vec> = args.rest(1)?; + let input = args.input; + + let mut rows: Vec<_> = and_rows.into_iter().map(|x| x.item as usize).collect(); + rows.push(row_number.item as usize); + rows.sort_unstable(); + + Ok(DropNthIterator { + input, + rows, + current: 0, + } + .into_output_stream()) +} + +struct DropNthIterator { + input: InputStream, + rows: Vec, + current: usize, +} + +impl Iterator for DropNthIterator { + type Item = Value; + + fn next(&mut self) -> Option { + loop { + if let Some(row) = self.rows.get(0) { + if self.current == *row { + self.rows.remove(0); + self.current += 1; + let _ = self.input.next(); + continue; + } else { + self.current += 1; + return self.input.next(); + } + } else { + return self.input.next(); + } + } + } +} diff --git a/crates/nu-command/src/commands/filters/nth.rs b/crates/nu-command/src/commands/filters/nth.rs index cbe31fa695..908026d247 100644 --- a/crates/nu-command/src/commands/filters/nth.rs +++ b/crates/nu-command/src/commands/filters/nth.rs @@ -112,16 +112,3 @@ impl Iterator for NthIterator { } } } - -#[cfg(test)] -mod tests { - use super::Nth; - use super::ShellError; - - #[test] - fn examples_work_as_expected() -> Result<(), ShellError> { - use crate::examples::test as test_examples; - - test_examples(Nth {}) - } -} diff --git a/crates/nu-command/src/commands/mod.rs b/crates/nu-command/src/commands/mod.rs index c2a8ac4aa5..41c7aa0f11 100644 --- a/crates/nu-command/src/commands/mod.rs +++ b/crates/nu-command/src/commands/mod.rs @@ -65,12 +65,16 @@ mod tests { fn full_tests() -> Vec { vec![ + whole_stream_command(Drop), + whole_stream_command(DropNth), + whole_stream_command(DropColumn), whole_stream_command(Append), whole_stream_command(GroupBy), whole_stream_command(Insert), whole_stream_command(MoveColumn), whole_stream_command(Update), whole_stream_command(Empty), + whole_stream_command(Nth), // whole_stream_command(Select), // whole_stream_command(Get), // Str Command Suite diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index 795feb6d43..20c14d21c4 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -150,6 +150,7 @@ pub fn create_default_context(interactive: bool) -> Result