From ef56d482b2c26996c2ffb59de98989838ac5f0e1 Mon Sep 17 00:00:00 2001 From: Stefan Stanciulescu Date: Sun, 31 Oct 2021 22:53:37 +0100 Subject: [PATCH] Port first command to engine-q --- crates/nu-command/src/default_context.rs | 1 + crates/nu-command/src/filters/first.rs | 86 ++++++++++++++++++++++++ crates/nu-command/src/filters/mod.rs | 2 + 3 files changed, 89 insertions(+) create mode 100644 crates/nu-command/src/filters/first.rs diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index 32cb38aa89..452c33f7c7 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -32,6 +32,7 @@ pub fn create_default_context() -> EngineState { Each, ExportDef, External, + First, For, From, FromJson, diff --git a/crates/nu-command/src/filters/first.rs b/crates/nu-command/src/filters/first.rs new file mode 100644 index 0000000000..68e121adb2 --- /dev/null +++ b/crates/nu-command/src/filters/first.rs @@ -0,0 +1,86 @@ +use nu_engine::CallExt; +use nu_protocol::ast::Call; +use nu_protocol::engine::{Command, EngineState, Stack}; +use nu_protocol::{Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value}; + +#[derive(Clone)] +pub struct First; + +impl Command for First { + fn name(&self) -> &str { + "first" + } + + fn signature(&self) -> Signature { + Signature::build("first").optional( + "rows", + SyntaxShape::Int, + "starting from the front, the number of rows to return", + ) + } + + fn usage(&self) -> &str { + "Show only the first number of rows." + } + + fn run( + &self, + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, + input: PipelineData, + ) -> Result { + first_helper(engine_state, stack, call, input) + } + + fn examples(&self) -> Vec { + vec![ + Example { + description: "Return the first item of a list/table", + example: "[1 2 3] | first", + result: Some(Value::List { + vals: vec![Value::test_int(1)], + span: Span::unknown(), + }), + }, + Example { + description: "Return the first 2 items of a list/table", + example: "[1 2 3] | first 2", + result: Some(Value::List { + vals: vec![Value::test_int(1), Value::test_int(2)], + span: Span::unknown(), + }), + }, + ] + } +} + +fn first_helper( + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, + input: PipelineData, +) -> Result { + let rows: Option = call.opt(engine_state, stack, 0)?; + let rows_desired: usize = match rows { + Some(x) => x as usize, + None => 1, + }; + + Ok(Value::List { + vals: input.into_iter().take(rows_desired).collect(), + span: call.head, + } + .into_pipeline_data()) +} + +#[cfg(test)] +mod test { + use super::*; + #[test] + fn test_examples() { + use crate::test_examples; + + test_examples(First {}) + } +} diff --git a/crates/nu-command/src/filters/mod.rs b/crates/nu-command/src/filters/mod.rs index f322ca3092..34796069de 100644 --- a/crates/nu-command/src/filters/mod.rs +++ b/crates/nu-command/src/filters/mod.rs @@ -1,4 +1,5 @@ mod each; +mod first; mod get; mod last; mod length; @@ -10,6 +11,7 @@ mod where_; mod wrap; pub use each::Each; +pub use first::First; pub use get::Get; pub use last::Last; pub use length::Length;