diff --git a/crates/nu-command/src/filters/get.rs b/crates/nu-command/src/filters/get.rs index 3f12e66814..6dfc66ba56 100644 --- a/crates/nu-command/src/filters/get.rs +++ b/crates/nu-command/src/filters/get.rs @@ -51,55 +51,6 @@ If multiple cell paths are given, this will produce a list of values."# .category(Category::Filters) } - fn run( - &self, - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, - ) -> Result { - let span = call.head; - let mut cell_path: CellPath = call.req(engine_state, stack, 0)?; - let mut rest: Vec = call.rest(engine_state, stack, 1)?; - let ignore_errors = call.has_flag(engine_state, stack, "ignore-errors")?; - let sensitive = call.has_flag(engine_state, stack, "sensitive")?; - let metadata = input.metadata(); - - if ignore_errors { - cell_path.make_optional(); - for path in &mut rest { - path.make_optional(); - } - } - - if rest.is_empty() { - follow_cell_path_into_stream( - input, - engine_state.signals().clone(), - cell_path.members, - call.head, - !sensitive, - ) - } else { - let mut output = vec![]; - - let paths = std::iter::once(cell_path).chain(rest); - - let input = input.into_value(span)?; - - for path in paths { - let val = input.clone().follow_cell_path(&path.members, !sensitive); - - output.push(val?); - } - - Ok(output - .into_iter() - .into_pipeline_data(span, engine_state.signals().clone())) - } - .map(|x| x.set_metadata(metadata)) - } - fn examples(&self) -> Vec { vec![ Example { @@ -143,6 +94,92 @@ If multiple cell paths are given, this will produce a list of values."# }, ] } + + fn is_const(&self) -> bool { + true + } + + fn run_const( + &self, + working_set: &StateWorkingSet, + call: &Call, + input: PipelineData, + ) -> Result { + let cell_path: CellPath = call.req_const(working_set, 0)?; + let rest: Vec = call.rest_const(working_set, 1)?; + let ignore_errors = call.has_flag_const(working_set, "ignore-errors")?; + let sensitive = call.has_flag_const(working_set, "sensitive")?; + let metadata = input.metadata(); + action( + input, + cell_path, + rest, + ignore_errors, + sensitive, + working_set.permanent().signals().clone(), + call.head, + ) + .map(|x| x.set_metadata(metadata)) + } + + fn run( + &self, + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, + input: PipelineData, + ) -> Result { + let cell_path: CellPath = call.req(engine_state, stack, 0)?; + let rest: Vec = call.rest(engine_state, stack, 1)?; + let ignore_errors = call.has_flag(engine_state, stack, "ignore-errors")?; + let sensitive = call.has_flag(engine_state, stack, "sensitive")?; + let metadata = input.metadata(); + action( + input, + cell_path, + rest, + ignore_errors, + sensitive, + engine_state.signals().clone(), + call.head, + ) + .map(|x| x.set_metadata(metadata)) + } +} + +fn action( + input: PipelineData, + mut cell_path: CellPath, + mut rest: Vec, + ignore_errors: bool, + sensitive: bool, + signals: Signals, + span: Span, +) -> Result { + if ignore_errors { + cell_path.make_optional(); + for path in &mut rest { + path.make_optional(); + } + } + + if rest.is_empty() { + follow_cell_path_into_stream(input, signals, cell_path.members, span, !sensitive) + } else { + let mut output = vec![]; + + let paths = std::iter::once(cell_path).chain(rest); + + let input = input.into_value(span)?; + + for path in paths { + let val = input.clone().follow_cell_path(&path.members, !sensitive); + + output.push(val?); + } + + Ok(output.into_iter().into_pipeline_data(span, signals)) + } } // the PipelineData.follow_cell_path function, when given a diff --git a/crates/nu-command/tests/commands/get.rs b/crates/nu-command/tests/commands/get.rs index 049b5b2899..c5c1c02e95 100644 --- a/crates/nu-command/tests/commands/get.rs +++ b/crates/nu-command/tests/commands/get.rs @@ -207,3 +207,9 @@ fn ignore_multiple() { assert_eq!(actual.out, "[[null], [null]]"); } + +#[test] +fn test_const() { + let actual = nu!(r#"const x = [1 2 3] | get 1; $x"#); + assert_eq!(actual.out, "2"); +}