Move print_pipeline_data to nu-protocol (#5328)

This commit is contained in:
Reilly Wood 2022-04-25 16:44:57 -07:00 committed by GitHub
parent 3492d4015d
commit 187f2454c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 86 deletions

View File

@ -25,7 +25,6 @@ pub use print::Print;
pub use prompt::NushellPrompt;
pub use repl::evaluate_repl;
pub use syntax_highlight::NuHighlighter;
pub use util::print_pipeline_data;
pub use util::{eval_source, gather_parent_env_vars, get_init_cwd, report_error};
pub use validation::NuValidator;

View File

@ -34,7 +34,7 @@ impl Command for Print {
let head = call.head;
for arg in args {
crate::util::print_pipeline_data(arg.into_pipeline_data(), engine_state, stack)?;
arg.into_pipeline_data().print(engine_state, stack)?;
}
Ok(PipelineData::new(head))

View File

@ -4,94 +4,13 @@ use nu_engine::eval_block;
use nu_parser::{lex, parse, unescape_unquote_string, Token, TokenContents};
use nu_protocol::engine::StateWorkingSet;
use nu_protocol::{
ast::Call,
engine::{EngineState, Stack},
PipelineData, ShellError, Span, Value,
};
#[cfg(windows)]
use nu_utils::enable_vt_processing;
use std::io::Write;
use std::path::PathBuf;
pub fn print_pipeline_data(
input: PipelineData,
engine_state: &EngineState,
stack: &mut Stack,
) -> Result<(), ShellError> {
// If the table function is in the declarations, then we can use it
// to create the table value that will be printed in the terminal
let config = engine_state.get_config();
let stdout = std::io::stdout();
if let PipelineData::ExternalStream {
stdout: stream,
exit_code,
..
} = input
{
if let Some(stream) = stream {
for s in stream {
let _ = stdout.lock().write_all(s?.as_binary()?);
}
}
// Make sure everything has finished
if let Some(exit_code) = exit_code {
let _: Vec<_> = exit_code.into_iter().collect();
}
return Ok(());
}
match engine_state.find_decl("table".as_bytes()) {
Some(decl_id) => {
let table = engine_state.get_decl(decl_id).run(
engine_state,
stack,
&Call::new(Span::new(0, 0)),
input,
)?;
for item in table {
let stdout = std::io::stdout();
if let Value::Error { error } = item {
return Err(error);
}
let mut out = item.into_string("\n", config);
out.push('\n');
match stdout.lock().write_all(out.as_bytes()) {
Ok(_) => (),
Err(err) => eprintln!("{}", err),
};
}
}
None => {
for item in input {
let stdout = std::io::stdout();
if let Value::Error { error } = item {
return Err(error);
}
let mut out = item.into_string("\n", config);
out.push('\n');
match stdout.lock().write_all(out.as_bytes()) {
Ok(_) => (),
Err(err) => eprintln!("{}", err),
};
}
}
};
Ok(())
}
// This will collect environment variables from std::env and adds them to a stack.
//
// In order to ensure the values have spans, it first creates a dummy file, writes the collected
@ -329,7 +248,7 @@ pub fn eval_source(
set_last_exit_code(stack, 0);
}
if let Err(err) = print_pipeline_data(pipeline_data, engine_state, stack) {
if let Err(err) = pipeline_data.print(engine_state, stack) {
let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &err);

View File

@ -1,6 +1,13 @@
use std::sync::{atomic::AtomicBool, Arc};
use std::{
io::Write,
sync::{atomic::AtomicBool, Arc},
};
use crate::{ast::PathMember, Config, ListStream, RawStream, ShellError, Span, Value};
use crate::{
ast::{Call, PathMember},
engine::{EngineState, Stack},
Config, ListStream, RawStream, ShellError, Span, Value,
};
/// The foundational abstraction for input and output to commands
///
@ -408,6 +415,81 @@ impl PipelineData {
}
}
}
pub fn print(self, engine_state: &EngineState, stack: &mut Stack) -> Result<(), ShellError> {
// If the table function is in the declarations, then we can use it
// to create the table value that will be printed in the terminal
let config = engine_state.get_config();
let stdout = std::io::stdout();
if let PipelineData::ExternalStream {
stdout: stream,
exit_code,
..
} = self
{
if let Some(stream) = stream {
for s in stream {
let _ = stdout.lock().write_all(s?.as_binary()?);
}
}
// Make sure everything has finished
if let Some(exit_code) = exit_code {
let _: Vec<_> = exit_code.into_iter().collect();
}
return Ok(());
}
match engine_state.find_decl("table".as_bytes()) {
Some(decl_id) => {
let table = engine_state.get_decl(decl_id).run(
engine_state,
stack,
&Call::new(Span::new(0, 0)),
self,
)?;
for item in table {
let stdout = std::io::stdout();
if let Value::Error { error } = item {
return Err(error);
}
let mut out = item.into_string("\n", config);
out.push('\n');
match stdout.lock().write_all(out.as_bytes()) {
Ok(_) => (),
Err(err) => eprintln!("{}", err),
};
}
}
None => {
for item in self {
let stdout = std::io::stdout();
if let Value::Error { error } = item {
return Err(error);
}
let mut out = item.into_string("\n", config);
out.push('\n');
match stdout.lock().write_all(out.as_bytes()) {
Ok(_) => (),
Err(err) => eprintln!("{}", err),
};
}
}
};
Ok(())
}
}
pub struct PipelineIterator(PipelineData);