mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 09:25:38 +02:00
ListStream
touchup (#12524)
# Description Does some misc changes to `ListStream`: - Moves it into its own module/file separate from `RawStream`. - `ListStream`s now have an associated `Span`. - This required changes to `ListStreamInfo` in `nu-plugin`. Note sure if this is a breaking change for the plugin protocol. - Hides the internals of `ListStream` but also adds a few more methods. - This includes two functions to more easily alter a stream (these take a `ListStream` and return a `ListStream` instead of having to go through the whole `into_pipeline_data(..)` route). - `map`: takes a `FnMut(Value) -> Value` - `modify`: takes a function to modify the inner stream.
This commit is contained in:
@ -62,6 +62,7 @@ impl Command for Do {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let block: Closure = call.req(engine_state, caller_stack, 0)?;
|
||||
let rest: Vec<Value> = call.rest(engine_state, caller_stack, 1)?;
|
||||
let ignore_all_errors = call.has_flag(engine_state, caller_stack, "ignore-errors")?;
|
||||
@ -75,7 +76,7 @@ impl Command for Do {
|
||||
let mut callee_stack = caller_stack.captures_to_stack_preserve_out_dest(block.captures);
|
||||
let block = engine_state.get_block(block.block_id);
|
||||
|
||||
bind_args_to(&mut callee_stack, &block.signature, rest, call.head)?;
|
||||
bind_args_to(&mut callee_stack, &block.signature, rest, head)?;
|
||||
let eval_block_with_early_return = get_eval_block_with_early_return(engine_state);
|
||||
let result = eval_block_with_early_return(engine_state, &mut callee_stack, block, input);
|
||||
|
||||
@ -117,7 +118,7 @@ impl Command for Do {
|
||||
None,
|
||||
)
|
||||
})
|
||||
.err_span(call.head)
|
||||
.err_span(head)
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
@ -148,13 +149,9 @@ impl Command for Do {
|
||||
None
|
||||
};
|
||||
|
||||
let mut exit_code_ctrlc = None;
|
||||
let exit_code: Vec<Value> = match exit_code {
|
||||
None => vec![],
|
||||
Some(exit_code_stream) => {
|
||||
exit_code_ctrlc.clone_from(&exit_code_stream.ctrlc);
|
||||
exit_code_stream.into_iter().collect()
|
||||
}
|
||||
Some(exit_code_stream) => exit_code_stream.into_iter().collect(),
|
||||
};
|
||||
if let Some(Value::Int { val: code, .. }) = exit_code.last() {
|
||||
if *code != 0 {
|
||||
@ -174,10 +171,7 @@ impl Command for Do {
|
||||
span,
|
||||
None,
|
||||
)),
|
||||
exit_code: Some(ListStream::from_stream(
|
||||
exit_code.into_iter(),
|
||||
exit_code_ctrlc,
|
||||
)),
|
||||
exit_code: Some(ListStream::new(exit_code.into_iter(), span, None)),
|
||||
span,
|
||||
metadata,
|
||||
trim_end_newline,
|
||||
@ -205,21 +199,15 @@ impl Command for Do {
|
||||
Ok(PipelineData::Value(Value::Error { .. }, ..)) | Err(_) if ignore_shell_errors => {
|
||||
Ok(PipelineData::empty())
|
||||
}
|
||||
Ok(PipelineData::ListStream(ls, metadata)) if ignore_shell_errors => {
|
||||
// check if there is a `Value::Error` in given list stream first.
|
||||
let mut values = vec![];
|
||||
let ctrlc = ls.ctrlc.clone();
|
||||
for v in ls {
|
||||
if let Value::Error { .. } = v {
|
||||
values.push(Value::nothing(call.head));
|
||||
Ok(PipelineData::ListStream(stream, metadata)) if ignore_shell_errors => {
|
||||
let stream = stream.map(move |value| {
|
||||
if let Value::Error { .. } = value {
|
||||
Value::nothing(head)
|
||||
} else {
|
||||
values.push(v)
|
||||
value
|
||||
}
|
||||
}
|
||||
Ok(PipelineData::ListStream(
|
||||
ListStream::from_stream(values.into_iter(), ctrlc),
|
||||
metadata,
|
||||
))
|
||||
});
|
||||
Ok(PipelineData::ListStream(stream, metadata))
|
||||
}
|
||||
r => r,
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
use nu_engine::{command_prelude::*, get_eval_block, get_eval_expression};
|
||||
use nu_protocol::ListStream;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct For;
|
||||
@ -88,7 +87,11 @@ impl Command for For {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::List { vals, .. } => {
|
||||
for (idx, x) in ListStream::from_stream(vals.into_iter(), ctrlc).enumerate() {
|
||||
for (idx, x) in vals.into_iter().enumerate() {
|
||||
if nu_utils::ctrl_c::was_pressed(&ctrlc) {
|
||||
break;
|
||||
}
|
||||
|
||||
// with_env() is used here to ensure that each iteration uses
|
||||
// a different set of environment variables.
|
||||
// Hence, a 'cd' in the first loop won't affect the next loop.
|
||||
|
@ -26,13 +26,10 @@ impl Command for ScopeAliases {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
let head = call.head;
|
||||
let mut scope_data = ScopeData::new(engine_state, stack);
|
||||
scope_data.populate_decls();
|
||||
|
||||
Ok(scope_data.collect_aliases(span).into_pipeline_data(ctrlc))
|
||||
Ok(Value::list(scope_data.collect_aliases(head), head).into_pipeline_data())
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -26,13 +26,10 @@ impl Command for ScopeCommands {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
let head = call.head;
|
||||
let mut scope_data = ScopeData::new(engine_state, stack);
|
||||
scope_data.populate_decls();
|
||||
|
||||
Ok(scope_data.collect_commands(span).into_pipeline_data(ctrlc))
|
||||
Ok(Value::list(scope_data.collect_commands(head), head).into_pipeline_data())
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -26,13 +26,10 @@ impl Command for ScopeExterns {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
let head = call.head;
|
||||
let mut scope_data = ScopeData::new(engine_state, stack);
|
||||
scope_data.populate_decls();
|
||||
|
||||
Ok(scope_data.collect_externs(span).into_pipeline_data(ctrlc))
|
||||
Ok(Value::list(scope_data.collect_externs(head), head).into_pipeline_data())
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -26,13 +26,10 @@ impl Command for ScopeModules {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
let head = call.head;
|
||||
let mut scope_data = ScopeData::new(engine_state, stack);
|
||||
scope_data.populate_modules();
|
||||
|
||||
Ok(scope_data.collect_modules(span).into_pipeline_data(ctrlc))
|
||||
Ok(Value::list(scope_data.collect_modules(head), head).into_pipeline_data())
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
@ -26,13 +26,10 @@ impl Command for ScopeVariables {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
let head = call.head;
|
||||
let mut scope_data = ScopeData::new(engine_state, stack);
|
||||
scope_data.populate_vars();
|
||||
|
||||
Ok(scope_data.collect_vars(span).into_pipeline_data(ctrlc))
|
||||
Ok(Value::list(scope_data.collect_vars(head), head).into_pipeline_data())
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
|
Reference in New Issue
Block a user