node_child_process/
lib.rs1use js_sys::{Array, Object};
2use node_sys::*;
3use wasm_bindgen::prelude::*;
4
5#[wasm_bindgen(module = "node:child_process")]
6extern "C" {
7
8 pub fn spawn(cmd: &str) -> ChildProcess;
9
10 #[wasm_bindgen(js_name = spawn)]
11 pub fn spawn_with_args(cmd: &str, args: &SpawnArgs) -> ChildProcess;
12
13 #[wasm_bindgen(js_name = spawn)]
14 pub fn spawn_with_args_and_options(
15 cmd: &str,
16 args: &SpawnArgs,
17 options: &SpawnOptions,
18 ) -> ChildProcess;
19
20 #[wasm_bindgen(extends = Array)]
21 #[derive(Debug, Clone, PartialEq, Eq)]
22 pub type SpawnArgs;
23
24 #[wasm_bindgen(extends = Object)]
25 #[derive(Debug, Clone, PartialEq, Eq)]
26 pub type SpawnOptions;
27
28 #[wasm_bindgen(extends = EventEmitter)]
29 #[derive(Clone, Debug)]
30 pub type ChildProcess;
31
32 #[wasm_bindgen(method, getter)]
33 pub fn exit_code(this: &ChildProcess) -> u64;
34
35 #[wasm_bindgen(method, getter)]
36 pub fn pid(this: &ChildProcess) -> u64;
37
38 #[wasm_bindgen(method, getter)]
39 pub fn stdout(this: &ChildProcess) -> ReadableStream;
40
41 #[wasm_bindgen(method, getter)]
42 pub fn stderr(this: &ChildProcess) -> ReadableStream;
43
44 #[wasm_bindgen(method, getter)]
45 pub fn stdin(this: &ChildProcess) -> WritableStream;
46
47 #[wasm_bindgen(method)]
48 pub fn kill(this: &ChildProcess) -> bool;
49
50 #[wasm_bindgen(method, js_name=kill)]
51 fn kill_with_signal_impl(this: &ChildProcess, signal: JsValue) -> bool;
52}
53
54unsafe impl Send for ChildProcess {}
55unsafe impl Sync for ChildProcess {}
56
57pub enum KillSignal<'s> {
58 None,
59 SIGKILL,
60 SIGTERM,
61 Message(&'s str),
62 Code(u32),
63}
64
65impl ChildProcess {
66 pub fn kill_with_signal(self: &ChildProcess, signal: KillSignal) -> bool {
67 match signal {
68 KillSignal::None => self.kill(),
69 KillSignal::SIGKILL => self.kill_with_signal_impl(JsValue::from("SIGKILL")),
70 KillSignal::SIGTERM => self.kill_with_signal_impl(JsValue::from("SIGTERM")),
71 KillSignal::Message(str) => self.kill_with_signal_impl(JsValue::from(str)),
72 KillSignal::Code(code) => self.kill_with_signal_impl(JsValue::from(code)),
73 }
74 }
75}
76
77impl From<Vec<&str>> for SpawnArgs {
78 fn from(list: Vec<&str>) -> Self {
79 let array = Array::new();
80 for (index, value) in list.iter().enumerate() {
81 array.set(index as u32, JsValue::from(*value));
82 }
83
84 #[allow(unused_mut)]
85 let mut args: Self = ::wasm_bindgen::JsCast::unchecked_into(array);
86 args
87 }
88}
89
90impl From<&[&str]> for SpawnArgs {
91 fn from(list: &[&str]) -> Self {
92 let array = Array::new();
93 for (index, value) in list.iter().enumerate() {
94 array.set(index as u32, JsValue::from(*value));
95 }
96
97 #[allow(unused_mut)]
98 let mut args: Self = ::wasm_bindgen::JsCast::unchecked_into(array);
99 args
100 }
101}
102
103impl From<&[String]> for SpawnArgs {
104 fn from(list: &[String]) -> Self {
105 let array = Array::new();
106 for (index, value) in list.iter().enumerate() {
107 array.set(index as u32, JsValue::from(value));
108 }
109
110 #[allow(unused_mut)]
111 let mut args: Self = ::wasm_bindgen::JsCast::unchecked_into(array);
112 args
113 }
114}
115
116impl Default for SpawnOptions {
117 fn default() -> Self {
118 Self::new()
119 }
120}
121
122impl SpawnOptions {
123 pub fn new() -> Self {
127 #[allow(unused_mut)]
128 let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(Object::new());
129 ret
130 }
131
132 pub fn set(&self, key: &str, value: JsValue) -> &Self {
133 let r = ::js_sys::Reflect::set(self.as_ref(), &JsValue::from(key), &value);
134 debug_assert!(
135 r.is_ok(),
136 "setting properties should never fail on our dictionary objects"
137 );
138 let _ = r;
139 self
140 }
141
142 pub fn cwd(&self, cwd: &str) -> &Self {
143 self.set("cwd", JsValue::from(cwd))
144 }
145
146 pub fn env(&self, env: ProcessEnv) -> &Self {
147 self.set("env", JsValue::from(env))
148 }
149
150 pub fn argv0(&self, argv0: &str) -> &Self {
151 self.set("argv0", JsValue::from(argv0))
152 }
153
154 pub fn detached(&self, detached: bool) -> &Self {
155 self.set("detached", JsValue::from(detached))
156 }
157
158 pub fn uid(&self, uid: &str) -> &Self {
159 self.set("uid", JsValue::from(uid))
160 }
161
162 pub fn gid(&self, gid: &str) -> &Self {
163 self.set("gid", JsValue::from(gid))
164 }
165
166 pub fn serialization(&self, serialization: &str) -> &Self {
167 self.set("serialization", JsValue::from(serialization))
168 }
169
170 pub fn shell(&self, shell: bool) -> &Self {
171 self.set("shell", JsValue::from(shell))
172 }
173
174 pub fn shell_str(&self, shell: &str) -> &Self {
175 self.set("shell", JsValue::from(shell))
176 }
177
178 pub fn windows_verbatim_arguments(&self, args: bool) -> &Self {
179 self.set("windowsVerbatimArguments", JsValue::from(args))
180 }
181
182 pub fn windows_hide(&self, windows_hide: bool) -> &Self {
183 self.set("windowsHide", JsValue::from(windows_hide))
184 }
185
186 pub fn timeout(&self, timeout: u32) -> &Self {
187 self.set("timeout", JsValue::from(timeout))
188 }
189
190 pub fn kill_signal(&self, signal: u32) -> &Self {
193 self.set("killSignal", JsValue::from(signal))
194 }
195
196 pub fn kill_signal_str(&self, signal: &str) -> &Self {
197 self.set("killSignal", JsValue::from(signal))
198 }
199}