Improve empty pipelines (#7383)

# Description

This fix changes pipelines to allow them to actually be empty. Mapping
over empty pipelines gives empty pipelines. Empty pipelines immediately
return `None` when iterated.

This removes a some of where `Span::new(0, 0)` was coming from, though
there are other cases where we still use it.

# User-Facing Changes

None

# Tests + Formatting

Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- `cargo test --workspace` to check that all tests pass

# After Submitting

If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
This commit is contained in:
JT 2022-12-08 07:31:57 +13:00 committed by GitHub
parent d18587330a
commit eaec480f42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
80 changed files with 194 additions and 190 deletions

View File

@ -92,7 +92,7 @@ impl NuCompleter {
&self.engine_state, &self.engine_state,
&mut callee_stack, &mut callee_stack,
block, block,
PipelineData::new(span), PipelineData::empty(),
true, true,
true, true,
); );

View File

@ -67,7 +67,7 @@ impl Completer for CustomCompletion {
redirect_stdout: true, redirect_stdout: true,
redirect_stderr: true, redirect_stderr: true,
}, },
PipelineData::new(span), PipelineData::empty(),
); );
let mut custom_completion_options = None; let mut custom_completion_options = None;

View File

@ -8,7 +8,7 @@ use nu_path::canonicalize_with;
use nu_protocol::engine::{EngineState, Stack, StateWorkingSet}; use nu_protocol::engine::{EngineState, Stack, StateWorkingSet};
#[cfg(feature = "plugin")] #[cfg(feature = "plugin")]
use nu_protocol::Spanned; use nu_protocol::Spanned;
use nu_protocol::{HistoryFileFormat, PipelineData, Span}; use nu_protocol::{HistoryFileFormat, PipelineData};
use std::path::PathBuf; use std::path::PathBuf;
#[cfg(feature = "plugin")] #[cfg(feature = "plugin")]
@ -38,7 +38,7 @@ pub fn read_plugin_file(
stack, stack,
&contents, &contents,
&plugin_filename, &plugin_filename,
PipelineData::new(Span::new(0, 0)), PipelineData::empty(),
); );
} }
} }
@ -85,7 +85,7 @@ pub fn eval_config_contents(
stack, stack,
&contents, &contents,
&config_filename, &config_filename,
PipelineData::new(Span::new(0, 0)), PipelineData::empty(),
); );
// Merge the environment in case env vars changed in the config // Merge the environment in case env vars changed in the config

View File

@ -39,13 +39,7 @@ pub fn evaluate_file(
if working_set.find_decl(b"main", &Type::Any).is_some() { if working_set.find_decl(b"main", &Type::Any).is_some() {
let args = format!("main {}", args.join(" ")); let args = format!("main {}", args.join(" "));
if !eval_source( if !eval_source(engine_state, stack, &file, &path, PipelineData::empty()) {
engine_state,
stack,
&file,
&path,
PipelineData::new(Span::new(0, 0)),
) {
std::process::exit(1); std::process::exit(1);
} }
if !eval_source(engine_state, stack, args.as_bytes(), "<commandline>", input) { if !eval_source(engine_state, stack, args.as_bytes(), "<commandline>", input) {

View File

@ -50,14 +50,13 @@ Since this command has no output, there is no point in piping it with other comm
let args: Vec<Value> = call.rest(engine_state, stack, 0)?; let args: Vec<Value> = call.rest(engine_state, stack, 0)?;
let no_newline = call.has_flag("no-newline"); let no_newline = call.has_flag("no-newline");
let to_stderr = call.has_flag("stderr"); let to_stderr = call.has_flag("stderr");
let head = call.head;
for arg in args { for arg in args {
arg.into_pipeline_data() arg.into_pipeline_data()
.print(engine_state, stack, no_newline, to_stderr)?; .print(engine_state, stack, no_newline, to_stderr)?;
} }
Ok(PipelineData::new(head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -4,7 +4,7 @@ use log::info;
use nu_engine::eval_subexpression; use nu_engine::eval_subexpression;
use nu_protocol::{ use nu_protocol::{
engine::{EngineState, Stack, StateWorkingSet}, engine::{EngineState, Stack, StateWorkingSet},
Config, PipelineData, Span, Value, Config, PipelineData, Value,
}; };
use reedline::Prompt; use reedline::Prompt;
@ -37,12 +37,8 @@ fn get_prompt_string(
let block = engine_state.get_block(block_id); let block = engine_state.get_block(block_id);
let mut stack = stack.captures_to_stack(&captures); let mut stack = stack.captures_to_stack(&captures);
// Use eval_subexpression to force a redirection of output, so we can use everything in prompt // Use eval_subexpression to force a redirection of output, so we can use everything in prompt
let ret_val = eval_subexpression( let ret_val =
engine_state, eval_subexpression(engine_state, &mut stack, block, PipelineData::empty());
&mut stack,
block,
PipelineData::new(Span::new(0, 0)), // Don't try this at home, 0 span is ignored
);
info!( info!(
"get_prompt_string (block) {}:{}:{}", "get_prompt_string (block) {}:{}:{}",
file!(), file!(),
@ -62,12 +58,7 @@ fn get_prompt_string(
Value::Block { val: block_id, .. } => { Value::Block { val: block_id, .. } => {
let block = engine_state.get_block(block_id); let block = engine_state.get_block(block_id);
// Use eval_subexpression to force a redirection of output, so we can use everything in prompt // Use eval_subexpression to force a redirection of output, so we can use everything in prompt
let ret_val = eval_subexpression( let ret_val = eval_subexpression(engine_state, stack, block, PipelineData::empty());
engine_state,
stack,
block,
PipelineData::new(Span::new(0, 0)), // Don't try this at home, 0 span is ignored
);
info!( info!(
"get_prompt_string (block) {}:{}:{}", "get_prompt_string (block) {}:{}:{}",
file!(), file!(),

View File

@ -149,7 +149,7 @@ pub fn evaluate_repl(
stack, stack,
s.item.as_bytes(), s.item.as_bytes(),
&format!("entry #{}", entry_num), &format!("entry #{}", entry_num),
PipelineData::new(Span::new(0, 0)), PipelineData::empty(),
); );
engine_state.merge_env(stack, get_guaranteed_cwd(engine_state, stack))?; engine_state.merge_env(stack, get_guaranteed_cwd(engine_state, stack))?;
} }
@ -431,7 +431,7 @@ pub fn evaluate_repl(
stack, stack,
s.as_bytes(), s.as_bytes(),
&format!("entry #{}", entry_num), &format!("entry #{}", entry_num),
PipelineData::new(Span::new(0, 0)), PipelineData::empty(),
); );
} }
let cmd_duration = start_time.elapsed(); let cmd_duration = start_time.elapsed();
@ -637,7 +637,7 @@ pub fn eval_string_with_input(
let input_as_pipeline_data = match input { let input_as_pipeline_data = match input {
Some(input) => PipelineData::Value(input, None), Some(input) => PipelineData::Value(input, None),
None => PipelineData::new(Span::test_data()), None => PipelineData::empty(),
}; };
eval_block( eval_block(
@ -722,7 +722,7 @@ pub fn eval_hook(
val: "condition".to_string(), val: "condition".to_string(),
span: value_span, span: value_span,
}; };
let mut output = PipelineData::new(Span::new(0, 0)); let mut output = PipelineData::empty();
let code_path = PathMember::String { let code_path = PathMember::String {
val: "code".to_string(), val: "code".to_string(),
@ -823,7 +823,7 @@ pub fn eval_hook(
}; };
engine_state.merge_delta(delta)?; engine_state.merge_delta(delta)?;
let input = PipelineData::new(value_span); let input = PipelineData::empty();
let var_ids: Vec<VarId> = vars let var_ids: Vec<VarId> = vars
.into_iter() .into_iter()
@ -943,7 +943,7 @@ pub fn run_hook_block(
) -> Result<Value, ShellError> { ) -> Result<Value, ShellError> {
let block = engine_state.get_block(block_id); let block = engine_state.get_block(block_id);
let input = optional_input.unwrap_or_else(|| PipelineData::new(span)); let input = optional_input.unwrap_or_else(PipelineData::empty);
let mut callee_stack = stack.gather_captures(&block.captures); let mut callee_stack = stack.gather_captures(&block.captures);

View File

@ -43,10 +43,10 @@ impl Command for Alias {
&self, &self,
_engine_state: &EngineState, _engine_state: &EngineState,
_stack: &mut Stack, _stack: &mut Stack,
call: &Call, _call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -37,14 +37,13 @@ impl Command for Ast {
call: &Call, call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let head = call.head;
let pipeline: Spanned<String> = call.req(engine_state, stack, 0)?; let pipeline: Spanned<String> = call.req(engine_state, stack, 0)?;
let mut working_set = StateWorkingSet::new(engine_state); let mut working_set = StateWorkingSet::new(engine_state);
let (output, err) = parse(&mut working_set, None, pipeline.item.as_bytes(), false, &[]); let (output, err) = parse(&mut working_set, None, pipeline.item.as_bytes(), false, &[]);
eprintln!("output: {:#?}\nerror: {:#?}", output, err); eprintln!("output: {:#?}\nerror: {:#?}", output, err);
Ok(PipelineData::new(head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -36,10 +36,10 @@ impl Command for Def {
&self, &self,
_engine_state: &EngineState, _engine_state: &EngineState,
_stack: &mut Stack, _stack: &mut Stack,
call: &Call, _call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -62,10 +62,10 @@ def-env cd_with_fallback [arg = ""] {
&self, &self,
_engine_state: &EngineState, _engine_state: &EngineState,
_stack: &mut Stack, _stack: &mut Stack,
call: &Call, _call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -169,9 +169,9 @@ impl Command for Do {
trim_end_newline, trim_end_newline,
}), }),
Ok(PipelineData::Value(Value::Error { .. }, ..)) if ignore_shell_errors => { Ok(PipelineData::Value(Value::Error { .. }, ..)) if ignore_shell_errors => {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
Err(_) if ignore_shell_errors => Ok(PipelineData::new(call.head)), Err(_) if ignore_shell_errors => Ok(PipelineData::empty()),
r => r, r => r,
} }
} }

View File

@ -39,10 +39,10 @@ impl Command for ExportAlias {
&self, &self,
_engine_state: &EngineState, _engine_state: &EngineState,
_stack: &mut Stack, _stack: &mut Stack,
call: &Call, _call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -36,10 +36,10 @@ impl Command for ExportDef {
&self, &self,
_engine_state: &EngineState, _engine_state: &EngineState,
_stack: &mut Stack, _stack: &mut Stack,
call: &Call, _call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -62,10 +62,10 @@ export def-env cd_with_fallback [arg = ""] {
&self, &self,
_engine_state: &EngineState, _engine_state: &EngineState,
_stack: &mut Stack, _stack: &mut Stack,
call: &Call, _call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -35,10 +35,10 @@ impl Command for ExportExtern {
&self, &self,
_engine_state: &EngineState, _engine_state: &EngineState,
_stack: &mut Stack, _stack: &mut Stack,
call: &Call, _call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -34,10 +34,10 @@ impl Command for ExportUse {
&self, &self,
_engine_state: &EngineState, _engine_state: &EngineState,
_stack: &mut Stack, _stack: &mut Stack,
call: &Call, _call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -35,10 +35,10 @@ impl Command for Extern {
&self, &self,
_engine_state: &EngineState, _engine_state: &EngineState,
_stack: &mut Stack, _stack: &mut Stack,
call: &Call, _call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -110,7 +110,7 @@ impl Command for For {
&engine_state, &engine_state,
stack, stack,
&block, &block,
PipelineData::new(head), PipelineData::empty(),
redirect_stdout, redirect_stdout,
redirect_stderr, redirect_stderr,
) { ) {
@ -155,7 +155,7 @@ impl Command for For {
&engine_state, &engine_state,
stack, stack,
&block, &block,
PipelineData::new(head), PipelineData::empty(),
redirect_stdout, redirect_stdout,
redirect_stderr, redirect_stderr,
) { ) {
@ -181,14 +181,14 @@ impl Command for For {
&engine_state, &engine_state,
stack, stack,
&block, &block,
PipelineData::new(head), PipelineData::empty(),
redirect_stdout, redirect_stdout,
redirect_stderr, redirect_stderr,
)? )?
.into_value(head); .into_value(head);
} }
} }
Ok(PipelineData::new(head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -62,7 +62,7 @@ This command is a parser keyword. For details, check:
stack.remove_env_var(engine_state, &env_var_name.item); stack.remove_env_var(engine_state, &env_var_name.item);
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -63,7 +63,7 @@ impl Command for HideEnv {
} }
} }
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -102,7 +102,7 @@ impl Command for If {
.map(|res| res.0) .map(|res| res.0)
} }
} else { } else {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
} }
x => Err(ShellError::CantConvert( x => Err(ShellError::CantConvert(

View File

@ -32,7 +32,7 @@ impl Command for Ignore {
input: PipelineData, input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
input.into_value(call.head); input.into_value(call.head);
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -73,7 +73,7 @@ impl Command for Let {
//println!("Adding: {:?} to {}", rhs, var_id); //println!("Adding: {:?} to {}", rhs, var_id);
stack.add_var(var_id, rhs.into_value(call.head)); stack.add_var(var_id, rhs.into_value(call.head));
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -55,7 +55,7 @@ impl Command for Loop {
engine_state, engine_state,
stack, stack,
block, block,
PipelineData::new(call.head), PipelineData::empty(),
call.redirect_stdout, call.redirect_stdout,
call.redirect_stderr, call.redirect_stderr,
) { ) {
@ -73,7 +73,7 @@ impl Command for Loop {
} }
} }
} }
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -35,10 +35,10 @@ impl Command for Module {
&self, &self,
_engine_state: &EngineState, _engine_state: &EngineState,
_stack: &mut Stack, _stack: &mut Stack,
call: &Call, _call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -73,7 +73,7 @@ impl Command for Mut {
//println!("Adding: {:?} to {}", rhs, var_id); //println!("Adding: {:?} to {}", rhs, var_id);
stack.add_var(var_id, rhs.into_value(call.head)); stack.add_var(var_id, rhs.into_value(call.head));
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -88,7 +88,7 @@ impl Command for OverlayHide {
stack.add_env_var(name, val); stack.add_env_var(name, val);
} }
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -49,7 +49,7 @@ This command is a parser keyword. For details, check:
stack.add_overlay(name_arg.item); stack.add_overlay(name_arg.item);
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -172,7 +172,7 @@ impl Command for OverlayUse {
caller_stack.add_overlay(overlay_name); caller_stack.add_overlay(overlay_name);
} }
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -49,10 +49,10 @@ impl Command for Register {
&self, &self,
_engine_state: &EngineState, _engine_state: &EngineState,
_stack: &mut Stack, _stack: &mut Stack,
call: &Call, _call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -71,12 +71,12 @@ impl Command for Try {
engine_state, engine_state,
stack, stack,
catch_block, catch_block,
PipelineData::new(call.head), PipelineData::empty(),
false, false,
false, false,
) )
} else { } else {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
} }
// external command may fail to run // external command may fail to run
@ -118,12 +118,12 @@ impl Command for Try {
engine_state, engine_state,
stack, stack,
catch_block, catch_block,
PipelineData::new(call.head), PipelineData::empty(),
false, false,
false, false,
) )
} else { } else {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
} else { } else {
Ok(PipelineData::ExternalStream { Ok(PipelineData::ExternalStream {

View File

@ -112,7 +112,7 @@ impl Command for Use {
)); ));
} }
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -63,7 +63,7 @@ impl Command for While {
engine_state, engine_state,
stack, stack,
block, block,
PipelineData::new(call.head), PipelineData::empty(),
call.redirect_stdout, call.redirect_stdout,
call.redirect_stderr, call.redirect_stderr,
) { ) {
@ -94,7 +94,7 @@ impl Command for While {
} }
} }
} }
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -22,7 +22,7 @@ pub fn test_dataframe(cmds: Vec<Box<dyn Command + 'static>>) {
let delta = { let delta = {
// Base functions that are needed for testing // Base functions that are needed for testing
// Try to keep this working set small to keep tests running as fast as possible // Try to keep this working set small to keep tests running as fast as possible
let mut working_set = StateWorkingSet::new(&*engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
working_set.add_decl(Box::new(Let)); working_set.add_decl(Box::new(Let));
working_set.add_decl(Box::new(ToDataFrame)); working_set.add_decl(Box::new(ToDataFrame));
working_set.add_decl(Box::new(ToLazyFrame)); working_set.add_decl(Box::new(ToLazyFrame));
@ -49,7 +49,7 @@ pub fn test_dataframe(cmds: Vec<Box<dyn Command + 'static>>) {
let start = std::time::Instant::now(); let start = std::time::Instant::now();
let (block, delta) = { let (block, delta) = {
let mut working_set = StateWorkingSet::new(&*engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let (output, err) = parse( let (output, err) = parse(
&mut working_set, &mut working_set,
None, None,
@ -75,7 +75,7 @@ pub fn test_dataframe(cmds: Vec<Box<dyn Command + 'static>>) {
&engine_state, &engine_state,
&mut stack, &mut stack,
&block, &block,
PipelineData::new(Span::test_data()), PipelineData::empty(),
true, true,
true, true,
) { ) {

View File

@ -108,6 +108,6 @@ impl Command for ConfigReset {
} }
} }
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
} }

View File

@ -50,7 +50,7 @@ impl Command for ExportEnv {
redirect_env(engine_state, caller_stack, &callee_stack); redirect_env(engine_state, caller_stack, &callee_stack);
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -57,7 +57,7 @@ impl Command for LetEnv {
} else { } else {
stack.add_env_var(env_var.item, rhs); stack.add_env_var(env_var.item, rhs);
} }
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -57,7 +57,7 @@ impl Command for LoadEnv {
stack.add_env_var(env_var, rhs); stack.add_env_var(env_var, rhs);
} }
} }
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
None => match input { None => match input {
PipelineData::Value(Value::Record { cols, vals, .. }, ..) => { PipelineData::Value(Value::Record { cols, vals, .. }, ..) => {
@ -81,7 +81,7 @@ impl Command for LoadEnv {
stack.add_env_var(env_var, rhs); stack.add_env_var(env_var, rhs);
} }
} }
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
_ => Err(ShellError::UnsupportedInput( _ => Err(ShellError::UnsupportedInput(
"'load-env' expects a single record".into(), "'load-env' expects a single record".into(),

View File

@ -59,7 +59,7 @@ mod test_examples {
let delta = { let delta = {
// Base functions that are needed for testing // Base functions that are needed for testing
// Try to keep this working set small to keep tests running as fast as possible // Try to keep this working set small to keep tests running as fast as possible
let mut working_set = StateWorkingSet::new(&*engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
working_set.add_decl(Box::new(Let)); working_set.add_decl(Box::new(Let));
working_set.add_decl(Box::new(Str)); working_set.add_decl(Box::new(Str));
working_set.add_decl(Box::new(StrJoin)); working_set.add_decl(Box::new(StrJoin));
@ -215,10 +215,10 @@ mod test_examples {
); );
engine_state engine_state
.merge_env(&mut stack, &cwd) .merge_env(&mut stack, cwd)
.expect("Error merging environment"); .expect("Error merging environment");
let empty_input = PipelineData::new(Span::test_data()); let empty_input = PipelineData::empty();
let result = eval(example.example, empty_input, cwd, engine_state); let result = eval(example.example, empty_input, cwd, engine_state);
// Note. Value implements PartialEq for Bool, Int, Float, String and Block // Note. Value implements PartialEq for Bool, Int, Float, String and Block
@ -320,7 +320,7 @@ mod test_examples {
block.pipelines[0].elements.truncate(&n_expressions - 1); block.pipelines[0].elements.truncate(&n_expressions - 1);
if !block.pipelines[0].elements.is_empty() { if !block.pipelines[0].elements.is_empty() {
let empty_input = PipelineData::new(Span::test_data()); let empty_input = PipelineData::empty();
Some(eval_block(block, empty_input, cwd, engine_state, delta)) Some(eval_block(block, empty_input, cwd, engine_state, delta))
} else { } else {
Some(Value::nothing(Span::test_data())) Some(Value::nothing(Span::test_data()))

View File

@ -196,7 +196,7 @@ impl Command for Cd {
match have_permission(&path_tointo) { match have_permission(&path_tointo) {
PermissionResult::PermissionOk => { PermissionResult::PermissionOk => {
stack.add_env_var("PWD".into(), path_value); stack.add_env_var("PWD".into(), path_value);
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
PermissionResult::PermissionDenied(reason) => Err(ShellError::IOError(format!( PermissionResult::PermissionDenied(reason) => Err(ShellError::IOError(format!(
"Cannot change directory to {}: {}", "Cannot change directory to {}: {}",

View File

@ -2,8 +2,7 @@ use nu_engine::CallExt;
use nu_protocol::ast::Call; use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{ use nu_protocol::{
Category, Example, PipelineData, RawStream, ShellError, Signature, Span, Spanned, SyntaxShape, Category, Example, PipelineData, RawStream, ShellError, Signature, Spanned, SyntaxShape, Value,
Value,
}; };
use std::fs::File; use std::fs::File;
use std::io::{BufWriter, Write}; use std::io::{BufWriter, Write};
@ -160,7 +159,7 @@ impl Command for Save {
file.flush()? file.flush()?
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
Value::Binary { val, .. } => { Value::Binary { val, .. } => {
if let Err(err) = file.write_all(&val) { if let Err(err) = file.write_all(&val) {
@ -169,7 +168,7 @@ impl Command for Save {
file.flush()? file.flush()?
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
Value::List { vals, .. } => { Value::List { vals, .. } => {
let val = vals let val = vals
@ -185,7 +184,7 @@ impl Command for Save {
file.flush()? file.flush()?
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
v => Err(ShellError::UnsupportedInput( v => Err(ShellError::UnsupportedInput(
format!("{:?} not supported", v.get_type()), format!("{:?} not supported", v.get_type()),
@ -194,7 +193,7 @@ impl Command for Save {
} }
} else { } else {
match input { match input {
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::new(span)), PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(stream), stdout: Some(stream),
stderr, stderr,
@ -202,16 +201,16 @@ impl Command for Save {
} => { } => {
// delegate a thread to redirect stderr to result. // delegate a thread to redirect stderr to result.
let handler = stderr.map(|stderr_stream| match stderr_file { let handler = stderr.map(|stderr_stream| match stderr_file {
Some(stderr_file) => std::thread::spawn(move || { Some(stderr_file) => {
stream_to_file(stderr_stream, stderr_file, span) std::thread::spawn(move || stream_to_file(stderr_stream, stderr_file))
}), }
None => std::thread::spawn(move || { None => std::thread::spawn(move || {
let _ = stderr_stream.into_bytes(); let _ = stderr_stream.into_bytes();
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
}), }),
}); });
let res = stream_to_file(stream, file, span); let res = stream_to_file(stream, file);
if let Some(h) = handler { if let Some(h) = handler {
match h.join() { match h.join() {
Err(err) => { Err(err) => {
@ -236,7 +235,7 @@ impl Command for Save {
file.flush()? file.flush()?
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
Value::Binary { val, .. } => { Value::Binary { val, .. } => {
if let Err(err) = file.write_all(&val) { if let Err(err) = file.write_all(&val) {
@ -245,7 +244,7 @@ impl Command for Save {
file.flush()? file.flush()?
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
Value::List { vals, .. } => { Value::List { vals, .. } => {
let val = vals let val = vals
@ -261,7 +260,7 @@ impl Command for Save {
file.flush()? file.flush()?
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
v => Err(ShellError::UnsupportedInput( v => Err(ShellError::UnsupportedInput(
format!("{:?} not supported", v.get_type()), format!("{:?} not supported", v.get_type()),
@ -303,11 +302,7 @@ impl Command for Save {
} }
} }
fn stream_to_file( fn stream_to_file(mut stream: RawStream, file: File) -> Result<PipelineData, ShellError> {
mut stream: RawStream,
file: File,
span: Span,
) -> Result<PipelineData, ShellError> {
let mut writer = BufWriter::new(file); let mut writer = BufWriter::new(file);
stream stream
@ -331,5 +326,5 @@ fn stream_to_file(
} }
Ok(()) Ok(())
}) })
.map(|_| PipelineData::new(span)) .map(|_| PipelineData::empty())
} }

View File

@ -190,7 +190,7 @@ impl Command for Touch {
} }
} }
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -271,7 +271,7 @@ impl Command for Watch {
} }
} }
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -72,6 +72,7 @@ fn getcol(
input: PipelineData, input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
match input { match input {
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::Value( PipelineData::Value(
Value::List { Value::List {
vals: input_vals, vals: input_vals,

View File

@ -156,6 +156,7 @@ with 'transpose' first."#
let redirect_stderr = call.redirect_stderr; let redirect_stderr = call.redirect_stderr;
match input { match input {
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::Value(Value::Range { .. }, ..) PipelineData::Value(Value::Range { .. }, ..)
| PipelineData::Value(Value::List { .. }, ..) | PipelineData::Value(Value::List { .. }, ..)
| PipelineData::ListStream { .. } => Ok(input | PipelineData::ListStream { .. } => Ok(input
@ -223,7 +224,7 @@ with 'transpose' first."#
} }
}) })
.into_pipeline_data(ctrlc)), .into_pipeline_data(ctrlc)),
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::new(call.head)), PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(stream), stdout: Some(stream),
.. ..

View File

@ -116,6 +116,7 @@ impl Command for EachWhile {
let redirect_stderr = call.redirect_stderr; let redirect_stderr = call.redirect_stderr;
match input { match input {
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::Value(Value::Range { .. }, ..) PipelineData::Value(Value::Range { .. }, ..)
| PipelineData::Value(Value::List { .. }, ..) | PipelineData::Value(Value::List { .. }, ..)
| PipelineData::ListStream { .. } => Ok(input | PipelineData::ListStream { .. } => Ok(input
@ -186,7 +187,7 @@ impl Command for EachWhile {
}) })
.fuse() .fuse()
.into_pipeline_data(ctrlc)), .into_pipeline_data(ctrlc)),
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::new(call.head)), PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(stream), stdout: Some(stream),
.. ..

View File

@ -103,6 +103,7 @@ fn empty(
.into_pipeline_data()) .into_pipeline_data())
} else { } else {
match input { match input {
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::ExternalStream { stdout, .. } => match stdout { PipelineData::ExternalStream { stdout, .. } => match stdout {
Some(s) => { Some(s) => {
let bytes = s.into_bytes(); let bytes = s.into_bytes();

View File

@ -321,6 +321,7 @@ fn find_with_rest_and_highlight(
let ls_colors = get_ls_colors(ls_colors_env_str); let ls_colors = get_ls_colors(ls_colors_env_str);
match input { match input {
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::Value(_, _) => input PipelineData::Value(_, _) => input
.map( .map(
move |mut x| match &mut x { move |mut x| match &mut x {
@ -446,7 +447,7 @@ fn find_with_rest_and_highlight(
) )
.into_pipeline_data(ctrlc) .into_pipeline_data(ctrlc)
.set_metadata(meta)), .set_metadata(meta)),
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::new(span)), PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(stream), stdout: Some(stream),
.. ..

View File

@ -110,7 +110,7 @@ impl Command for Last {
if let Some(last) = last { if let Some(last) = last {
Ok(last.into_pipeline_data().set_metadata(metadata)) Ok(last.into_pipeline_data().set_metadata(metadata))
} else { } else {
Ok(PipelineData::new(span).set_metadata(metadata)) Ok(PipelineData::empty().set_metadata(metadata))
} }
} }
} }

View File

@ -97,6 +97,7 @@ fn getcol(
input: PipelineData, input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
match input { match input {
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::Value( PipelineData::Value(
Value::List { Value::List {
vals: input_vals, vals: input_vals,

View File

@ -71,6 +71,7 @@ impl Command for Lines {
Ok(iter.into_pipeline_data(engine_state.ctrlc.clone())) Ok(iter.into_pipeline_data(engine_state.ctrlc.clone()))
} }
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::ListStream(stream, ..) => { PipelineData::ListStream(stream, ..) => {
let iter = stream let iter = stream
.into_iter() .into_iter()
@ -112,7 +113,7 @@ impl Command for Lines {
format!("Not supported input: {}", val.as_string()?), format!("Not supported input: {}", val.as_string()?),
head, head,
)), )),
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::new(head)), PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(stream), stdout: Some(stream),
.. ..

View File

@ -81,6 +81,7 @@ impl Command for ParEach {
let redirect_stderr = call.redirect_stderr; let redirect_stderr = call.redirect_stderr;
match input { match input {
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::Value(Value::Range { val, .. }, ..) => Ok(val PipelineData::Value(Value::Range { val, .. }, ..) => Ok(val
.into_range_iter(ctrlc.clone())? .into_range_iter(ctrlc.clone())?
.enumerate() .enumerate()
@ -272,7 +273,7 @@ impl Command for ParEach {
.into_iter() .into_iter()
.flatten() .flatten()
.into_pipeline_data(ctrlc)), .into_pipeline_data(ctrlc)),
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::new(call.head)), PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(stream), stdout: Some(stream),
.. ..

View File

@ -219,7 +219,7 @@ impl Command for Reduce {
engine_state, engine_state,
&mut stack, &mut stack,
block, block,
PipelineData::new(span), PipelineData::empty(),
// redirect stdout until its the last input value // redirect stdout until its the last input value
redirect_stdout || input_iter.peek().is_some(), redirect_stdout || input_iter.peek().is_some(),
redirect_stderr, redirect_stderr,

View File

@ -249,7 +249,7 @@ fn select(
Ok(v.into_pipeline_data().set_metadata(metadata)) Ok(v.into_pipeline_data().set_metadata(metadata))
} }
} }
_ => Ok(PipelineData::new(span)), _ => Ok(PipelineData::empty()),
} }
} }

View File

@ -96,7 +96,7 @@ impl Command for SkipUntil {
&engine_state, &engine_state,
&mut stack, &mut stack,
&block, &block,
PipelineData::new(span), PipelineData::empty(),
redirect_stdout, redirect_stdout,
redirect_stderr, redirect_stderr,
) )

View File

@ -97,7 +97,7 @@ impl Command for SkipWhile {
&engine_state, &engine_state,
&mut stack, &mut stack,
&block, &block,
PipelineData::new(span), PipelineData::empty(),
redirect_stdout, redirect_stdout,
redirect_stderr, redirect_stderr,
) )

View File

@ -92,7 +92,7 @@ impl Command for TakeUntil {
&engine_state, &engine_state,
&mut stack, &mut stack,
&block, &block,
PipelineData::new(span), PipelineData::empty(),
redirect_stdout, redirect_stdout,
redirect_stderr, redirect_stderr,
) )

View File

@ -92,7 +92,7 @@ impl Command for TakeWhile {
&engine_state, &engine_state,
&mut stack, &mut stack,
&block, &block,
PipelineData::new(span), PipelineData::empty(),
redirect_stdout, redirect_stdout,
redirect_stderr, redirect_stderr,
) )

View File

@ -62,6 +62,7 @@ impl Command for Where {
let redirect_stderr = call.redirect_stderr; let redirect_stderr = call.redirect_stderr;
match input { match input {
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::Value(Value::Range { .. }, ..) PipelineData::Value(Value::Range { .. }, ..)
| PipelineData::Value(Value::List { .. }, ..) | PipelineData::Value(Value::List { .. }, ..)
| PipelineData::ListStream { .. } => Ok(input | PipelineData::ListStream { .. } => Ok(input
@ -115,9 +116,7 @@ impl Command for Where {
} }
}) })
.into_pipeline_data(ctrlc)), .into_pipeline_data(ctrlc)),
PipelineData::ExternalStream { stdout: None, .. } => { PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
Ok(PipelineData::new(call.head))
}
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(stream), stdout: Some(stream),
.. ..

View File

@ -39,6 +39,7 @@ impl Command for Wrap {
let name: String = call.req(engine_state, stack, 0)?; let name: String = call.req(engine_state, stack, 0)?;
match input { match input {
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::Value(Value::Range { .. }, ..) PipelineData::Value(Value::Range { .. }, ..)
| PipelineData::Value(Value::List { .. }, ..) | PipelineData::Value(Value::List { .. }, ..)
| PipelineData::ListStream { .. } => Ok(input | PipelineData::ListStream { .. } => Ok(input

View File

@ -54,7 +54,7 @@ impl Command for History {
if clear { if clear {
let _ = std::fs::remove_file(history_path); let _ = std::fs::remove_file(history_path);
// TODO: FIXME also clear the auxiliary files when using sqlite // TODO: FIXME also clear the auxiliary files when using sqlite
Ok(PipelineData::new(head)) Ok(PipelineData::empty())
} else { } else {
let history_reader: Option<Box<dyn ReedlineHistory>> = let history_reader: Option<Box<dyn ReedlineHistory>> =
match engine_state.config.history_file_format { match engine_state.config.history_file_format {

View File

@ -176,7 +176,7 @@ impl Command for SubCommand {
file.flush()? file.flush()?
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
Value::Binary { val, .. } => { Value::Binary { val, .. } => {
if let Err(err) = file.write_all(&val) { if let Err(err) = file.write_all(&val) {
@ -185,7 +185,7 @@ impl Command for SubCommand {
file.flush()? file.flush()?
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
Value::List { vals, .. } => { Value::List { vals, .. } => {
let val = vals let val = vals
@ -201,7 +201,7 @@ impl Command for SubCommand {
file.flush()? file.flush()?
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
v => Err(ShellError::UnsupportedInput( v => Err(ShellError::UnsupportedInput(
format!("{:?} not supported", v.get_type()), format!("{:?} not supported", v.get_type()),
@ -211,7 +211,7 @@ impl Command for SubCommand {
} else { } else {
match value { match value {
PipelineData::ExternalStream { stdout: None, .. } => { PipelineData::ExternalStream { stdout: None, .. } => {
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(mut stream), stdout: Some(mut stream),
@ -240,7 +240,7 @@ impl Command for SubCommand {
} }
Ok(()) Ok(())
}) })
.map(|_| PipelineData::new(span)) .map(|_| PipelineData::empty())
} }
value => match value.into_value(span) { value => match value.into_value(span) {
Value::String { val, .. } => { Value::String { val, .. } => {
@ -250,7 +250,7 @@ impl Command for SubCommand {
file.flush()? file.flush()?
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
Value::Binary { val, .. } => { Value::Binary { val, .. } => {
if let Err(err) = file.write_all(&val) { if let Err(err) = file.write_all(&val) {
@ -259,7 +259,7 @@ impl Command for SubCommand {
file.flush()? file.flush()?
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
Value::List { vals, .. } => { Value::List { vals, .. } => {
let val = vals let val = vals
@ -275,7 +275,7 @@ impl Command for SubCommand {
file.flush()? file.flush()?
} }
Ok(PipelineData::new(span)) Ok(PipelineData::empty())
} }
v => Err(ShellError::UnsupportedInput( v => Err(ShellError::UnsupportedInput(
format!("{:?} not supported", v.get_type()), format!("{:?} not supported", v.get_type()),

View File

@ -99,7 +99,7 @@ impl Command for Enter {
stack.add_env_var("PWD".into(), new_path); stack.add_env_var("PWD".into(), new_path);
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -101,7 +101,7 @@ impl Command for Exit {
stack.add_env_var("PWD".into(), new_path); stack.add_env_var("PWD".into(), new_path);
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
} }

View File

@ -121,7 +121,7 @@ fn switch_shell(
stack.add_env_var("PWD".into(), new_path); stack.add_env_var("PWD".into(), new_path);
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
fn list_shells( fn list_shells(

View File

@ -180,7 +180,7 @@ fn detect_columns(
}) })
.into_pipeline_data(ctrlc)) .into_pipeline_data(ctrlc))
} else { } else {
Ok(PipelineData::new(name_span)) Ok(PipelineData::empty())
} }
} }

View File

@ -66,7 +66,7 @@ documentation link at https://docs.rs/encoding_rs/0.8.28/encoding_rs/#statics"#
let encoding: Spanned<String> = call.req(engine_state, stack, 0)?; let encoding: Spanned<String> = call.req(engine_state, stack, 0)?;
match input { match input {
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::new(call.head)), PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(stream), stdout: Some(stream),
.. ..

View File

@ -66,7 +66,7 @@ documentation link at https://docs.rs/encoding_rs/0.8.28/encoding_rs/#statics"#
let encoding: Spanned<String> = call.req(engine_state, stack, 0)?; let encoding: Spanned<String> = call.req(engine_state, stack, 0)?;
match input { match input {
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::new(call.head)), PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(stream), stdout: Some(stream),
.. ..

View File

@ -44,7 +44,7 @@ impl Command for Benchmark {
engine_state, engine_state,
&mut stack, &mut stack,
block, block,
PipelineData::new(call.head), PipelineData::empty(),
redirect_stdout, redirect_stdout,
redirect_stderr, redirect_stderr,
)? )?

View File

@ -88,7 +88,7 @@ prints out the list properly."#
use_grid_icons, use_grid_icons,
)?) )?)
} else { } else {
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
} }
PipelineData::ListStream(stream, ..) => { PipelineData::ListStream(stream, ..) => {
@ -106,7 +106,7 @@ prints out the list properly."#
)?) )?)
} else { } else {
// dbg!(data); // dbg!(data);
Ok(PipelineData::new(call.head)) Ok(PipelineData::empty())
} }
} }
PipelineData::Value(Value::Record { cols, vals, .. }, ..) => { PipelineData::Value(Value::Record { cols, vals, .. }, ..) => {

View File

@ -43,7 +43,7 @@ fn sets_the_column_from_a_block_full_stream_output() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
wrap content {content: null}
| update content { open --raw cargo_sample.toml | lines | first 5 } | update content { open --raw cargo_sample.toml | lines | first 5 }
| get content.1 | get content.1
| str contains "nu" | str contains "nu"
@ -58,7 +58,7 @@ fn sets_the_column_from_a_subexpression() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
wrap content {content: null}
| update content (open --raw cargo_sample.toml | lines | first 5) | update content (open --raw cargo_sample.toml | lines | first 5)
| get content.1 | get content.1
| str contains "nu" | str contains "nu"

View File

@ -43,7 +43,7 @@ fn sets_the_column_from_a_block_full_stream_output() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
wrap content {content: null}
| upsert content { open --raw cargo_sample.toml | lines | first 5 } | upsert content { open --raw cargo_sample.toml | lines | first 5 }
| get content.1 | get content.1
| str contains "nu" | str contains "nu"
@ -58,7 +58,7 @@ fn sets_the_column_from_a_subexpression() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
wrap content {content: null}
| upsert content (open --raw cargo_sample.toml | lines | first 5) | upsert content (open --raw cargo_sample.toml | lines | first 5)
| get content.1 | get content.1
| str contains "nu" | str contains "nu"

View File

@ -350,7 +350,7 @@ fn get_converted_value(
engine_state, engine_state,
&mut stack, &mut stack,
block, block,
PipelineData::new(val_span), PipelineData::new_with_metadata(None, val_span),
true, true,
true, true,
); );

View File

@ -339,10 +339,7 @@ pub fn eval_expression(
} }
Expr::Call(call) => { Expr::Call(call) => {
// FIXME: protect this collect with ctrl-c // FIXME: protect this collect with ctrl-c
Ok( Ok(eval_call(engine_state, stack, call, PipelineData::empty())?.into_value(call.head))
eval_call(engine_state, stack, call, PipelineData::new(call.head))?
.into_value(call.head),
)
} }
Expr::ExternalCall(head, args, is_subexpression) => { Expr::ExternalCall(head, args, is_subexpression) => {
let span = head.span; let span = head.span;
@ -352,7 +349,7 @@ pub fn eval_expression(
stack, stack,
head, head,
args, args,
PipelineData::new(span), PipelineData::empty(),
false, false,
false, false,
*is_subexpression, *is_subexpression,
@ -536,7 +533,7 @@ pub fn eval_expression(
// FIXME: protect this collect with ctrl-c // FIXME: protect this collect with ctrl-c
Ok( Ok(
eval_subexpression(engine_state, stack, block, PipelineData::new(expr.span))? eval_subexpression(engine_state, stack, block, PipelineData::empty())?
.into_value(expr.span), .into_value(expr.span),
) )
} }
@ -1087,14 +1084,28 @@ pub fn eval_block(
match engine_state.find_decl("table".as_bytes(), &[]) { match engine_state.find_decl("table".as_bytes(), &[]) {
Some(decl_id) => { Some(decl_id) => {
let table = engine_state.get_decl(decl_id).run( let table = engine_state.get_decl(decl_id);
engine_state,
stack,
&Call::new(Span::new(0, 0)),
input,
)?;
print_or_return(table, config)?; if let Some(block_id) = table.get_block_id() {
let block = engine_state.get_block(block_id);
eval_block(
engine_state,
stack,
block,
input,
redirect_stdout,
redirect_stderr,
)?;
} else {
let table = table.run(
engine_state,
stack,
&Call::new(Span::new(0, 0)),
input,
)?;
print_or_return(table, config)?;
}
} }
None => { None => {
print_or_return(input, config)?; print_or_return(input, config)?;
@ -1103,7 +1114,7 @@ pub fn eval_block(
} }
} }
input = PipelineData::new(Span::unknown()) input = PipelineData::empty()
} }
} }

View File

@ -5,6 +5,7 @@ use super::NuSpan;
pub fn collect_pipeline(input: PipelineData) -> (Vec<String>, Vec<Vec<Value>>) { pub fn collect_pipeline(input: PipelineData) -> (Vec<String>, Vec<Vec<Value>>) {
match input { match input {
PipelineData::Empty => (vec![], vec![]),
PipelineData::Value(value, ..) => collect_input(value), PipelineData::Value(value, ..) => collect_input(value),
PipelineData::ListStream(mut stream, ..) => { PipelineData::ListStream(mut stream, ..) => {
let mut records = vec![]; let mut records = vec![];

View File

@ -53,6 +53,7 @@ pub enum PipelineData {
metadata: Option<PipelineMetadata>, metadata: Option<PipelineMetadata>,
trim_end_newline: bool, trim_end_newline: bool,
}, },
Empty,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -67,19 +68,20 @@ pub enum DataSource {
} }
impl PipelineData { impl PipelineData {
pub fn new(span: Span) -> PipelineData {
PipelineData::Value(Value::Nothing { span }, None)
}
pub fn new_with_metadata(metadata: Option<PipelineMetadata>, span: Span) -> PipelineData { pub fn new_with_metadata(metadata: Option<PipelineMetadata>, span: Span) -> PipelineData {
PipelineData::Value(Value::Nothing { span }, metadata) PipelineData::Value(Value::Nothing { span }, metadata)
} }
pub fn empty() -> PipelineData {
PipelineData::Empty
}
pub fn metadata(&self) -> Option<PipelineMetadata> { pub fn metadata(&self) -> Option<PipelineMetadata> {
match self { match self {
PipelineData::ListStream(_, x) => x.clone(), PipelineData::ListStream(_, x) => x.clone(),
PipelineData::ExternalStream { metadata: x, .. } => x.clone(), PipelineData::ExternalStream { metadata: x, .. } => x.clone(),
PipelineData::Value(_, x) => x.clone(), PipelineData::Value(_, x) => x.clone(),
PipelineData::Empty => None,
} }
} }
@ -88,6 +90,7 @@ impl PipelineData {
PipelineData::ListStream(_, x) => *x = metadata, PipelineData::ListStream(_, x) => *x = metadata,
PipelineData::ExternalStream { metadata: x, .. } => *x = metadata, PipelineData::ExternalStream { metadata: x, .. } => *x = metadata,
PipelineData::Value(_, x) => *x = metadata, PipelineData::Value(_, x) => *x = metadata,
PipelineData::Empty => {}
} }
self self
@ -95,6 +98,7 @@ impl PipelineData {
pub fn is_nothing(&self) -> bool { pub fn is_nothing(&self) -> bool {
matches!(self, PipelineData::Value(Value::Nothing { .. }, ..)) matches!(self, PipelineData::Value(Value::Nothing { .. }, ..))
|| matches!(self, PipelineData::Empty)
} }
/// PipelineData doesn't always have a Span, but we can try! /// PipelineData doesn't always have a Span, but we can try!
@ -103,11 +107,13 @@ impl PipelineData {
PipelineData::ListStream(..) => None, PipelineData::ListStream(..) => None,
PipelineData::ExternalStream { span, .. } => Some(*span), PipelineData::ExternalStream { span, .. } => Some(*span),
PipelineData::Value(v, _) => v.span().ok(), PipelineData::Value(v, _) => v.span().ok(),
PipelineData::Empty => None,
} }
} }
pub fn into_value(self, span: Span) -> Value { pub fn into_value(self, span: Span) -> Value {
match self { match self {
PipelineData::Empty => Value::nothing(span),
PipelineData::Value(Value::Nothing { .. }, ..) => Value::nothing(span), PipelineData::Value(Value::Nothing { .. }, ..) => Value::nothing(span),
PipelineData::Value(v, ..) => v, PipelineData::Value(v, ..) => v,
PipelineData::ListStream(s, ..) => Value::List { PipelineData::ListStream(s, ..) => Value::List {
@ -202,6 +208,7 @@ impl PipelineData {
pub fn collect_string(self, separator: &str, config: &Config) -> Result<String, ShellError> { pub fn collect_string(self, separator: &str, config: &Config) -> Result<String, ShellError> {
match self { match self {
PipelineData::Empty => Ok(String::new()),
PipelineData::Value(v, ..) => Ok(v.into_string(separator, config)), PipelineData::Value(v, ..) => Ok(v.into_string(separator, config)),
PipelineData::ListStream(s, ..) => Ok(s.into_string(separator, config)), PipelineData::ListStream(s, ..) => Ok(s.into_string(separator, config)),
PipelineData::ExternalStream { stdout: None, .. } => Ok(String::new()), PipelineData::ExternalStream { stdout: None, .. } => Ok(String::new()),
@ -238,6 +245,7 @@ impl PipelineData {
span: Span, span: Span,
) -> Result<(String, Option<PipelineMetadata>), ShellError> { ) -> Result<(String, Option<PipelineMetadata>), ShellError> {
match self { match self {
PipelineData::Empty => Ok((String::new(), None)),
PipelineData::Value(Value::String { val, .. }, metadata) => Ok((val, metadata)), PipelineData::Value(Value::String { val, .. }, metadata) => Ok((val, metadata)),
PipelineData::Value(val, _) => { PipelineData::Value(val, _) => {
Err(ShellError::TypeMismatch("string".into(), val.span()?)) Err(ShellError::TypeMismatch("string".into(), val.span()?))
@ -306,10 +314,9 @@ impl PipelineData {
PipelineData::Value(Value::List { vals, .. }, ..) => { PipelineData::Value(Value::List { vals, .. }, ..) => {
Ok(vals.into_iter().map(f).into_pipeline_data(ctrlc)) Ok(vals.into_iter().map(f).into_pipeline_data(ctrlc))
} }
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::ListStream(stream, ..) => Ok(stream.map(f).into_pipeline_data(ctrlc)), PipelineData::ListStream(stream, ..) => Ok(stream.map(f).into_pipeline_data(ctrlc)),
PipelineData::ExternalStream { stdout: None, .. } => { PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
Ok(PipelineData::new(Span::unknown()))
}
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(stream), stdout: Some(stream),
trim_end_newline, trim_end_newline,
@ -359,15 +366,14 @@ impl PipelineData {
F: FnMut(Value) -> U + 'static + Send, F: FnMut(Value) -> U + 'static + Send,
{ {
match self { match self {
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::Value(Value::List { vals, .. }, ..) => { PipelineData::Value(Value::List { vals, .. }, ..) => {
Ok(vals.into_iter().flat_map(f).into_pipeline_data(ctrlc)) Ok(vals.into_iter().flat_map(f).into_pipeline_data(ctrlc))
} }
PipelineData::ListStream(stream, ..) => { PipelineData::ListStream(stream, ..) => {
Ok(stream.flat_map(f).into_pipeline_data(ctrlc)) Ok(stream.flat_map(f).into_pipeline_data(ctrlc))
} }
PipelineData::ExternalStream { stdout: None, .. } => { PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::Empty),
Ok(PipelineData::new(Span::unknown()))
}
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(stream), stdout: Some(stream),
trim_end_newline, trim_end_newline,
@ -414,13 +420,12 @@ impl PipelineData {
F: FnMut(&Value) -> bool + 'static + Send, F: FnMut(&Value) -> bool + 'static + Send,
{ {
match self { match self {
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::Value(Value::List { vals, .. }, ..) => { PipelineData::Value(Value::List { vals, .. }, ..) => {
Ok(vals.into_iter().filter(f).into_pipeline_data(ctrlc)) Ok(vals.into_iter().filter(f).into_pipeline_data(ctrlc))
} }
PipelineData::ListStream(stream, ..) => Ok(stream.filter(f).into_pipeline_data(ctrlc)), PipelineData::ListStream(stream, ..) => Ok(stream.filter(f).into_pipeline_data(ctrlc)),
PipelineData::ExternalStream { stdout: None, .. } => { PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::Empty),
Ok(PipelineData::new(Span::unknown()))
}
PipelineData::ExternalStream { PipelineData::ExternalStream {
stdout: Some(stream), stdout: Some(stream),
trim_end_newline, trim_end_newline,
@ -440,7 +445,7 @@ impl PipelineData {
if f(&v) { if f(&v) {
Ok(v.into_pipeline_data()) Ok(v.into_pipeline_data())
} else { } else {
Ok(PipelineData::new(collected.span)) Ok(PipelineData::new_with_metadata(None, collected.span))
} }
} else { } else {
let v = Value::Binary { let v = Value::Binary {
@ -451,7 +456,7 @@ impl PipelineData {
if f(&v) { if f(&v) {
Ok(v.into_pipeline_data()) Ok(v.into_pipeline_data())
} else { } else {
Ok(PipelineData::new(collected.span)) Ok(PipelineData::new_with_metadata(None, collected.span))
} }
} }
} }
@ -636,6 +641,7 @@ impl Iterator for PipelineIterator {
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
match &mut self.0 { match &mut self.0 {
PipelineData::Empty => None,
PipelineData::Value(Value::Nothing { .. }, ..) => None, PipelineData::Value(Value::Nothing { .. }, ..) => None,
PipelineData::Value(v, ..) => Some(std::mem::take(v)), PipelineData::Value(v, ..) => Some(std::mem::take(v)),
PipelineData::ListStream(stream, ..) => stream.next(), PipelineData::ListStream(stream, ..) => stream.next(),

View File

@ -3,7 +3,7 @@ use nu_cli::{eval_config_contents, eval_source, report_error};
use nu_parser::ParseError; use nu_parser::ParseError;
use nu_path::canonicalize_with; use nu_path::canonicalize_with;
use nu_protocol::engine::{EngineState, Stack, StateWorkingSet}; use nu_protocol::engine::{EngineState, Stack, StateWorkingSet};
use nu_protocol::{PipelineData, Span, Spanned}; use nu_protocol::{PipelineData, Spanned};
use nu_utils::{get_default_config, get_default_env}; use nu_utils::{get_default_config, get_default_env};
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
@ -128,7 +128,7 @@ pub(crate) fn read_default_env_file(engine_state: &mut EngineState, stack: &mut
stack, stack,
config_file.as_bytes(), config_file.as_bytes(),
"default_env.nu", "default_env.nu",
PipelineData::new(Span::new(0, 0)), PipelineData::empty(),
); );
info!("read_config_file {}:{}:{}", file!(), line!(), column!()); info!("read_config_file {}:{}:{}", file!(), line!(), column!());
@ -164,7 +164,7 @@ fn eval_default_config(
} else { } else {
"default_config.nu" "default_config.nu"
}, },
PipelineData::new(Span::new(0, 0)), PipelineData::empty(),
); );
// Merge the environment in case env vars changed in the config // Merge the environment in case env vars changed in the config

View File

@ -22,8 +22,8 @@ use nu_path::canonicalize_with;
use nu_protocol::{ use nu_protocol::{
ast::{Call, Expr, Expression, PipelineElement}, ast::{Call, Expr, Expression, PipelineElement},
engine::{Command, EngineState, Stack, StateWorkingSet}, engine::{Command, EngineState, Stack, StateWorkingSet},
Category, Example, IntoPipelineData, PipelineData, RawStream, ShellError, Signature, Span, Category, Example, IntoPipelineData, PipelineData, RawStream, ShellError, Signature, Spanned,
Spanned, SyntaxShape, Value, SyntaxShape, Value,
}; };
use nu_utils::stdout_write_all_and_flush; use nu_utils::stdout_write_all_and_flush;
use std::{ use std::{
@ -323,7 +323,7 @@ fn main() -> Result<()> {
trim_end_newline: false, trim_end_newline: false,
} }
} else { } else {
PipelineData::new(Span::new(0, 0)) PipelineData::empty()
}; };
info!("redirect_stdin {}:{}:{}", file!(), line!(), column!()); info!("redirect_stdin {}:{}:{}", file!(), line!(), column!());

View File

@ -220,7 +220,7 @@ pub fn nu_repl() {
outcome_err(&engine_state, &err); outcome_err(&engine_state, &err);
} }
let input = PipelineData::new(Span::test_data()); let input = PipelineData::empty();
let config = engine_state.get_config(); let config = engine_state.get_config();
match eval_block(&engine_state, &mut stack, &block, input, false, false) { match eval_block(&engine_state, &mut stack, &block, input, false, false) {