diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index a856716468..014ff2ff95 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -115,6 +115,7 @@ pub fn create_default_context() -> EngineState { Mv, ParEach, Parse, + Prepend, Ps, Range, Random, diff --git a/crates/nu-command/src/filters/mod.rs b/crates/nu-command/src/filters/mod.rs index 9805e0809d..718a006bf0 100644 --- a/crates/nu-command/src/filters/mod.rs +++ b/crates/nu-command/src/filters/mod.rs @@ -10,6 +10,7 @@ mod last; mod length; mod lines; mod par_each; +mod prepend; mod range; mod reject; mod reverse; @@ -33,6 +34,7 @@ pub use last::Last; pub use length::Length; pub use lines::Lines; pub use par_each::ParEach; +pub use prepend::Prepend; pub use range::Range; pub use reject::Reject; pub use reverse::Reverse; diff --git a/crates/nu-command/src/filters/prepend.rs b/crates/nu-command/src/filters/prepend.rs new file mode 100644 index 0000000000..c50ce2764c --- /dev/null +++ b/crates/nu-command/src/filters/prepend.rs @@ -0,0 +1,122 @@ +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 Prepend; + +impl Command for Prepend { + fn name(&self) -> &str { + "prepend" + } + + fn signature(&self) -> nu_protocol::Signature { + Signature::build("prepend") + .required("row", SyntaxShape::Any, "the row to prepend") + .category(Category::Filters) + } + + fn usage(&self) -> &str { + "Prepend a row to the table." + } + + fn examples(&self) -> Vec { + vec![ + Example { + example: "[1,2,3,4] | prepend 0", + description: "Prepend 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: "[2,3,4] | prepend [0,1]", + description: "Prepend two 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: "[2,nu,4,shell] | prepend [0,1,rocks]", + description: "Prepend Ints and Strings", + result: Some(Value::List { + vals: vec![ + Value::test_int(0), + Value::test_int(1), + Value::test_string("rocks"), + 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(vec + .into_iter() + .chain(input) + .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(Prepend {}) + } +}