1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
mod bindings;
mod builder;
mod command_group_config;
pub use builder::*;
pub use command_group_config::CommandGroupConfig;
use nu_protocol::{
ast::{Block, Call},
engine::{EngineState, Stack},
PipelineData, Span,
};
use crate::{
argument::IntoArgument,
error::{CrateError, CrateResult},
utils::parse_nu_script,
NewEmpty,
};
#[derive(Clone)]
pub struct Context {
engine_state: EngineState,
stack: Stack,
}
impl Context {
pub fn builder() -> ContextBuilder {
ContextBuilder::default()
}
pub fn eval_block(&mut self, block: &Block, input: PipelineData) -> CrateResult<PipelineData> {
nu_engine::eval_block(
&self.engine_state,
&mut self.stack,
block,
input,
false,
false,
)
.map_err(CrateError::from)
}
pub fn eval_raw<S: ToString>(
&mut self,
contents: S,
input: PipelineData,
) -> CrateResult<PipelineData> {
let block = parse_nu_script(&mut self.engine_state, contents.to_string())?;
self.eval_block(&block, input)
}
pub fn has_fn<S: AsRef<str>>(&mut self, name: S) -> bool {
self.engine_state
.find_decl(name.as_ref().as_bytes(), &vec![])
.is_some()
}
pub fn call_fn<S: AsRef<str>, I: IntoIterator<Item = A>, A: IntoArgument>(
&mut self,
name: S,
args: I,
) -> CrateResult<PipelineData> {
let args = args
.into_iter()
.map(|a| a.into_argument().into_nu_argument())
.collect::<Vec<_>>();
let decl_id = self
.engine_state
.find_decl(name.as_ref().as_bytes(), &vec![])
.ok_or_else(|| CrateError::FunctionNotFound(name.as_ref().to_string()))?;
let call = Call {
decl_id,
head: Span::empty(),
arguments: args,
redirect_stdout: true,
redirect_stderr: true,
};
let data = nu_engine::eval_call(
&self.engine_state,
&mut self.stack,
&call,
PipelineData::empty(),
)?;
Ok(data)
}
pub fn print_pipeline(&mut self, pipeline: PipelineData) -> CrateResult<()> {
pipeline.print(&self.engine_state, &mut self.stack, false, false)?;
Ok(())
}
pub fn print_pipeline_stderr(&mut self, pipeline: PipelineData) -> CrateResult<()> {
pipeline.print(&self.engine_state, &mut self.stack, false, true)?;
Ok(())
}
}