diff --git a/crates/nu-cli/src/cli.rs b/crates/nu-cli/src/cli.rs index 46701f6493..3249f8bc49 100644 --- a/crates/nu-cli/src/cli.rs +++ b/crates/nu-cli/src/cli.rs @@ -297,6 +297,7 @@ pub fn create_default_context( whole_stream_command(Last), whole_stream_command(Skip), whole_stream_command(Nth), + whole_stream_command(Drop), per_item_command(Format), per_item_command(Where), whole_stream_command(Compact), diff --git a/crates/nu-cli/src/commands.rs b/crates/nu-cli/src/commands.rs index 9a05d9339f..60d3098e03 100644 --- a/crates/nu-cli/src/commands.rs +++ b/crates/nu-cli/src/commands.rs @@ -20,6 +20,7 @@ pub(crate) mod cp; pub(crate) mod date; pub(crate) mod debug; pub(crate) mod default; +pub(crate) mod drop; pub(crate) mod du; pub(crate) mod each; pub(crate) mod echo; @@ -129,6 +130,7 @@ pub(crate) use cp::Cpy; pub(crate) use date::Date; pub(crate) use debug::Debug; pub(crate) use default::Default; +pub(crate) use drop::Drop; pub(crate) use du::Du; pub(crate) use each::Each; pub(crate) use echo::Echo; diff --git a/crates/nu-cli/src/commands/drop.rs b/crates/nu-cli/src/commands/drop.rs new file mode 100644 index 0000000000..ea3eac6b38 --- /dev/null +++ b/crates/nu-cli/src/commands/drop.rs @@ -0,0 +1,60 @@ +use crate::commands::WholeStreamCommand; +use crate::context::CommandRegistry; +use crate::prelude::*; +use nu_errors::ShellError; +use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, Value}; +use nu_source::Tagged; + +pub struct Drop; + +#[derive(Deserialize)] +pub struct DropArgs { + rows: Option>, +} + +impl WholeStreamCommand for Drop { + fn name(&self) -> &str { + "drop" + } + + fn signature(&self) -> Signature { + Signature::build("drop").optional( + "rows", + SyntaxShape::Number, + "starting from the back, the number of rows to drop", + ) + } + + fn usage(&self) -> &str { + "Drop the last number of rows." + } + + fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + args.process(registry, drop)?.run() + } +} + +fn drop(DropArgs { rows }: DropArgs, context: RunnableContext) -> Result { + let stream = async_stream! { + let v: Vec<_> = context.input.into_vec().await; + + let rows_to_drop = if let Some(quantity) = rows { + *quantity as usize + } else { + 1 + }; + + if rows_to_drop < v.len() { + let k = v.len() - rows_to_drop; + for x in v[0..k].iter() { + let y: Value = x.clone(); + yield ReturnSuccess::value(y) + } + } + }; + Ok(stream.to_output_stream()) +} diff --git a/crates/nu-cli/tests/commands/drop.rs b/crates/nu-cli/tests/commands/drop.rs new file mode 100644 index 0000000000..947dc99753 --- /dev/null +++ b/crates/nu-cli/tests/commands/drop.rs @@ -0,0 +1,11 @@ +use nu_test_support::nu; + +#[test] +fn drop_rows() { + let actual = nu!( + cwd: "tests/fixtures/formats", + r#"echo '[{"foo": 3}, {"foo": 8}, {"foo": 4}]' | from-json | drop 2 | get foo | sum | echo $it"# + ); + + assert_eq!(actual, "3"); +} diff --git a/crates/nu-cli/tests/commands/mod.rs b/crates/nu-cli/tests/commands/mod.rs index 0302f3d583..596e5c02e9 100644 --- a/crates/nu-cli/tests/commands/mod.rs +++ b/crates/nu-cli/tests/commands/mod.rs @@ -5,6 +5,7 @@ mod cd; mod compact; mod cp; mod default; +mod drop; mod each; mod edit; mod enter;