1use log::info;
2use nu_engine::eval_block;
3use nu_parser::parse;
4use nu_protocol::{
5 cli_error::report_compile_error,
6 debugger::WithoutDebug,
7 engine::{EngineState, Stack, StateWorkingSet},
8 report_parse_error, report_parse_warning, PipelineData, ShellError, Spanned, Value,
9};
10use std::sync::Arc;
11
12use crate::util::print_pipeline;
13
14#[derive(Default)]
15pub struct EvaluateCommandsOpts {
16 pub table_mode: Option<Value>,
17 pub error_style: Option<Value>,
18 pub no_newline: bool,
19}
20
21pub fn evaluate_commands(
23 commands: &Spanned<String>,
24 engine_state: &mut EngineState,
25 stack: &mut Stack,
26 input: PipelineData,
27 opts: EvaluateCommandsOpts,
28) -> Result<(), ShellError> {
29 let EvaluateCommandsOpts {
30 table_mode,
31 error_style,
32 no_newline,
33 } = opts;
34
35 if let Some(e_style) = error_style {
37 match e_style.coerce_str()?.parse() {
38 Ok(e_style) => {
39 Arc::make_mut(&mut engine_state.config).error_style = e_style;
40 }
41 Err(err) => {
42 return Err(ShellError::GenericError {
43 error: "Invalid value for `--error-style`".into(),
44 msg: err.into(),
45 span: Some(e_style.span()),
46 help: None,
47 inner: vec![],
48 });
49 }
50 }
51 }
52
53 let (block, delta) = {
55 if let Some(ref t_mode) = table_mode {
56 Arc::make_mut(&mut engine_state.config).table.mode =
57 t_mode.coerce_str()?.parse().unwrap_or_default();
58 }
59
60 let mut working_set = StateWorkingSet::new(engine_state);
61
62 let output = parse(&mut working_set, None, commands.item.as_bytes(), false);
63 if let Some(warning) = working_set.parse_warnings.first() {
64 report_parse_warning(&working_set, warning);
65 }
66
67 if let Some(err) = working_set.parse_errors.first() {
68 report_parse_error(&working_set, err);
69 std::process::exit(1);
70 }
71
72 if let Some(err) = working_set.compile_errors.first() {
73 report_compile_error(&working_set, err);
74 std::process::exit(1);
75 }
76
77 (output, working_set.render())
78 };
79
80 engine_state.merge_delta(delta)?;
82
83 let pipeline = eval_block::<WithoutDebug>(engine_state, stack, &block, input)?;
85
86 if let PipelineData::Value(Value::Error { error, .. }, ..) = pipeline {
87 return Err(*error);
88 }
89
90 if let Some(t_mode) = table_mode {
91 Arc::make_mut(&mut engine_state.config).table.mode =
92 t_mode.coerce_str()?.parse().unwrap_or_default();
93 }
94
95 print_pipeline(engine_state, stack, pipeline, no_newline)?;
96
97 info!("evaluate {}:{}:{}", file!(), line!(), column!());
98
99 Ok(())
100}