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:
Ian Manske
2024-05-05 16:00:59 +00:00
committed by GitHub
parent 3143ded374
commit e879d4ecaf
106 changed files with 957 additions and 874 deletions

View File

@ -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,
}

View File

@ -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.

View File

@ -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> {

View File

@ -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> {

View File

@ -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> {

View File

@ -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> {

View File

@ -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> {