From adb7eeb7409fb94daff36aea0fd79c47d53f4b43 Mon Sep 17 00:00:00 2001 From: Michael Angerman Date: Thu, 18 Nov 2021 11:16:04 -0800 Subject: [PATCH] port over the append command from nushell (#345) --- crates/nu-command/src/default_context.rs | 1 + crates/nu-command/src/filters/append.rs | 121 +++++++++++++++++++++++ crates/nu-command/src/filters/mod.rs | 2 + 3 files changed, 124 insertions(+) create mode 100644 crates/nu-command/src/filters/append.rs diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index 58e64ff21b..5dde288849 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -23,6 +23,7 @@ pub fn create_default_context() -> EngineState { // TODO: sort default context items categorically bind_command!( Alias, + Append, Benchmark, BuildString, Cd, diff --git a/crates/nu-command/src/filters/append.rs b/crates/nu-command/src/filters/append.rs new file mode 100644 index 0000000000..eba6b56c43 --- /dev/null +++ b/crates/nu-command/src/filters/append.rs @@ -0,0 +1,121 @@ +use nu_engine::CallExt; +use nu_protocol::ast::Call; +use nu_protocol::engine::{Command, EngineState, Stack}; +use nu_protocol::{ + Category, Example, IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, Span, + SyntaxShape, Value, +}; + +#[derive(Clone)] +pub struct Append; + +impl Command for Append { + fn name(&self) -> &str { + "append" + } + + fn signature(&self) -> nu_protocol::Signature { + Signature::build("append") + .required("row", SyntaxShape::Any, "the row to append") + .category(Category::Filters) + } + + fn usage(&self) -> &str { + "Append a row to the table." + } + + fn examples(&self) -> Vec { + vec![ + Example { + example: "[0,1,2,3] | append 4", + description: "Append one Int item", + result: Some(Value::List { + vals: vec![ + Value::test_int(0), + Value::test_int(1), + Value::test_int(2), + Value::test_int(3), + Value::test_int(4), + ], + span: Span::unknown(), + }), + }, + Example { + example: "[0,1] | append [2,3,4]", + description: "Append three Int items", + result: Some(Value::List { + vals: vec![ + Value::test_int(0), + Value::test_int(1), + Value::test_int(2), + Value::test_int(3), + Value::test_int(4), + ], + span: Span::unknown(), + }), + }, + Example { + example: "[0,1] | append [2,nu,4,shell]", + description: "Append Ints and Strings", + result: Some(Value::List { + vals: vec![ + Value::test_int(0), + Value::test_int(1), + Value::test_int(2), + Value::test_string("nu"), + Value::test_int(4), + Value::test_string("shell"), + ], + span: Span::unknown(), + }), + }, + ] + } + + fn run( + &self, + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, + input: PipelineData, + ) -> Result { + let val: Value = call.req(engine_state, stack, 0)?; + let vec: Vec = process_value(val); + + Ok(input + .into_iter() + .chain(vec) + .into_iter() + .into_pipeline_data(engine_state.ctrlc.clone())) + } +} + +fn process_value(val: Value) -> Vec { + match val { + Value::List { + vals: input_vals, + span: _, + } => { + let mut output = vec![]; + for input_val in input_vals { + output.push(input_val); + } + output + } + _ => { + vec![val] + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_examples() { + use crate::test_examples; + + test_examples(Append {}) + } +} diff --git a/crates/nu-command/src/filters/mod.rs b/crates/nu-command/src/filters/mod.rs index bf93145d5d..b5a21af226 100644 --- a/crates/nu-command/src/filters/mod.rs +++ b/crates/nu-command/src/filters/mod.rs @@ -1,3 +1,4 @@ +mod append; mod collect; mod each; mod first; @@ -15,6 +16,7 @@ mod where_; mod wrap; mod zip; +pub use append::Append; pub use collect::Collect; pub use each::Each; pub use first::First;