rhai_process/
registration.rs

1use crate::command_builder::CommandBuilder;
2use crate::config::Config;
3use crate::pipe_builder::PipeBuilder;
4use crate::pipeline_executor::PipelineExecutor;
5use crate::RhaiArray;
6use rhai::packages::Package;
7use rhai::plugin::*;
8use rhai::{Engine, FnPtr, ImmutableString, Map as RhaiMap, Module, NativeCallContext, Shared};
9use std::sync::Arc;
10
11pub fn module(config: Config) -> Module {
12    let shared = Arc::new(config);
13    let mut module = Module::new();
14    attach_custom_types(&mut module);
15
16    {
17        let config = Arc::clone(&shared);
18        module.set_native_fn("cmd", move |args: RhaiArray| {
19            CommandBuilder::new(Arc::clone(&config), args)
20        });
21    }
22
23    module
24}
25
26pub fn register(engine: &mut Engine, config: Config) {
27    ProcessPackage::new(config).register_into_engine(engine);
28}
29
30pub fn builder_module() -> Module {
31    let mut module = exported_module!(builder_api_module);
32    attach_custom_types(&mut module);
33    module
34}
35
36#[derive(Clone)]
37pub struct ProcessPackage {
38    builder_module: Shared<Module>,
39    process_module: Shared<Module>,
40}
41
42impl ProcessPackage {
43    pub fn new(config: Config) -> Self {
44        Self {
45            builder_module: builder_module().into(),
46            process_module: module(config).into(),
47        }
48    }
49}
50
51impl Package for ProcessPackage {
52    fn init(_: &mut Module) {}
53
54    fn as_shared_module(&self) -> Shared<Module> {
55        self.builder_module.clone()
56    }
57
58    fn register_into_engine(&self, engine: &mut Engine) -> &Self {
59        engine.register_global_module(self.builder_module.clone());
60        engine.register_global_module(self.process_module.clone());
61        self
62    }
63}
64
65fn attach_custom_types(module: &mut Module) {
66    module.set_custom_type::<CommandBuilder>("CommandBuilder");
67    module.set_custom_type::<PipeBuilder>("PipeBuilder");
68    module.set_custom_type::<PipelineExecutor>("PipelineExecutor");
69}
70
71#[export_module]
72pub mod builder_api_module {
73    use super::*;
74
75    #[rhai_fn(name = "env", return_raw)]
76    pub fn builder_env(builder: CommandBuilder, map: RhaiMap) -> crate::RhaiResult<CommandBuilder> {
77        builder.with_env_map(map)
78    }
79
80    #[rhai_fn(name = "env_var", return_raw)]
81    pub fn builder_env_var(
82        builder: CommandBuilder,
83        key: ImmutableString,
84        value: ImmutableString,
85    ) -> crate::RhaiResult<CommandBuilder> {
86        builder.with_env_var(key.into(), value.into())
87    }
88
89    #[rhai_fn(name = "pipe", return_raw)]
90    pub fn builder_pipe(
91        builder: CommandBuilder,
92        next: CommandBuilder,
93    ) -> crate::RhaiResult<PipeBuilder> {
94        builder.pipe(next)
95    }
96
97    #[rhai_fn(name = "build")]
98    pub fn builder_build(builder: CommandBuilder) -> PipelineExecutor {
99        builder.build()
100    }
101
102    #[rhai_fn(name = "pipe", return_raw)]
103    pub fn pipeline_pipe(
104        pipeline: PipeBuilder,
105        next: CommandBuilder,
106    ) -> crate::RhaiResult<PipeBuilder> {
107        pipeline.pipe(next)
108    }
109
110    #[rhai_fn(name = "build")]
111    pub fn pipeline_build(pipeline: PipeBuilder) -> PipelineExecutor {
112        pipeline.build()
113    }
114
115    #[rhai_fn(name = "cwd", return_raw)]
116    pub fn executor_cwd(
117        executor: PipelineExecutor,
118        path: ImmutableString,
119    ) -> crate::RhaiResult<PipelineExecutor> {
120        executor.cwd(path.into())
121    }
122
123    #[rhai_fn(name = "timeout", return_raw)]
124    pub fn executor_timeout(
125        executor: PipelineExecutor,
126        timeout: rhai::INT,
127    ) -> crate::RhaiResult<PipelineExecutor> {
128        executor.timeout(timeout)
129    }
130
131    #[rhai_fn(name = "allow_exit_codes", return_raw)]
132    pub fn executor_exit_codes(
133        executor: PipelineExecutor,
134        codes: RhaiArray,
135    ) -> crate::RhaiResult<PipelineExecutor> {
136        executor.allow_exit_codes(codes)
137    }
138
139    #[rhai_fn(name = "run", return_raw)]
140    pub fn executor_run(executor: PipelineExecutor) -> crate::RhaiResult<RhaiMap> {
141        executor.run()
142    }
143
144    #[rhai_fn(name = "run_stream", return_raw)]
145    pub fn executor_run_stream_default(
146        context: NativeCallContext,
147        executor: PipelineExecutor,
148    ) -> crate::RhaiResult<RhaiMap> {
149        executor.run_stream(&context, None, None)
150    }
151
152    #[rhai_fn(name = "run_stream", return_raw)]
153    pub fn executor_run_stream_stdout(
154        context: NativeCallContext,
155        executor: PipelineExecutor,
156        stdout_cb: FnPtr,
157    ) -> crate::RhaiResult<RhaiMap> {
158        executor.run_stream(&context, Some(stdout_cb), None)
159    }
160
161    #[rhai_fn(name = "run_stream", return_raw)]
162    pub fn executor_run_stream_both(
163        context: NativeCallContext,
164        executor: PipelineExecutor,
165        stdout_cb: FnPtr,
166        stderr_cb: FnPtr,
167    ) -> crate::RhaiResult<RhaiMap> {
168        executor.run_stream(&context, Some(stdout_cb), Some(stderr_cb))
169    }
170}