diff --git a/crates/nu-command/src/example_test.rs b/crates/nu-command/src/example_test.rs index ff3edb3dc9..c3f4bcdd70 100644 --- a/crates/nu-command/src/example_test.rs +++ b/crates/nu-command/src/example_test.rs @@ -10,7 +10,7 @@ pub fn test_examples(cmd: impl Command + 'static) { mod test_examples { use super::super::{ Ansi, Date, Enumerate, Filter, First, Flatten, From, Get, Into, IntoDatetime, IntoString, - Math, MathRound, ParEach, Path, PathParse, Random, Sort, SortBy, Split, SplitColumn, + Math, MathRound, ParEach, Path, PathParse, Random, Seq, Sort, SortBy, Split, SplitColumn, SplitRow, Str, StrJoin, StrLength, StrReplace, Update, Url, Values, Wrap, }; use crate::{Each, To}; @@ -87,6 +87,7 @@ mod test_examples { working_set.add_decl(Box::new(PathParse)); working_set.add_decl(Box::new(ParEach)); working_set.add_decl(Box::new(Random)); + working_set.add_decl(Box::new(Seq)); working_set.add_decl(Box::new(Sort)); working_set.add_decl(Box::new(SortBy)); working_set.add_decl(Box::new(Split)); diff --git a/crates/nu-command/src/filters/zip.rs b/crates/nu-command/src/filters/zip.rs index b8fe208169..6477f69bda 100644 --- a/crates/nu-command/src/filters/zip.rs +++ b/crates/nu-command/src/filters/zip.rs @@ -1,4 +1,4 @@ -use nu_engine::CallExt; +use nu_engine::{eval_block_with_early_return, CallExt}; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{ @@ -71,6 +71,14 @@ impl Command for Zip { Example { example: "1..3 | zip 4..6", description: "Zip two ranges", + result: Some(Value::list( + vec![test_row_1.clone(), test_row_2.clone(), test_row_3.clone()], + Span::test_data(), + )), + }, + Example { + example: "seq 1 3 | zip { seq 4 600000000 }", + description: "Zip two streams", result: Some(Value::list( vec![test_row_1, test_row_2, test_row_3], Span::test_data(), @@ -91,14 +99,31 @@ impl Command for Zip { call: &Call, input: PipelineData, ) -> Result { - let other: Value = call.req(engine_state, stack, 0)?; let head = call.head; let ctrlc = engine_state.ctrlc.clone(); let metadata = input.metadata(); + let other: PipelineData = match call.req(engine_state, stack, 0)? { + // If a closure was provided, evaluate it and consume its stream output + Value::Closure { val, .. } => { + let block = engine_state.get_block(val.block_id); + let mut stack = stack.captures_to_stack(val.captures); + eval_block_with_early_return( + engine_state, + &mut stack, + block, + PipelineData::Empty, + true, + false, + )? + } + // If any other value, use it as-is. + val => val.into_pipeline_data(), + }; + Ok(input .into_iter() - .zip(other.into_pipeline_data()) + .zip(other) .map(move |(x, y)| Value::list(vec![x, y], head)) .into_pipeline_data_with_metadata(metadata, ctrlc)) }