@@ -30,7 +30,8 @@ pub enum Buffer {
30
30
}
31
31
32
32
impl Buffer {
33
- /// Creates a new buffer.
33
+ /// Creates a `Buffer` instance, either containing raw bytes or text
34
+ /// based on the `is_raw` flag.
34
35
pub fn new ( is_raw : bool ) -> Buffer {
35
36
if is_raw {
36
37
Buffer :: Raw ( Vec :: new ( ) )
@@ -80,25 +81,24 @@ impl Buffer {
80
81
}
81
82
}
82
83
83
- /// A event sent to the command callback .
84
+ /// Event emitted by child process execution .
84
85
#[ derive( Clone , Debug , Deserialize , Eq , PartialEq , Serialize ) ]
85
86
#[ serde( tag = "type" , content = "data" , rename_all = "snake_case" ) ]
86
- pub enum CommandEvent {
87
- /// If configured for raw output, all bytes written to stderr.
88
- /// Otherwise, bytes until a newline (\n) or carriage return (\r) is
89
- /// found.
90
- Stderr ( Buffer ) ,
91
-
92
- /// If configured for raw output, all bytes written to stdout.
93
- /// Otherwise, bytes until a newline (\n) or carriage return (\r) is
94
- /// found.
87
+ pub enum ChildProcessEvent {
88
+ /// Raw or line-buffered stdout output. If configured for raw output,
89
+ /// all bytes written to stdout. Otherwise, bytes until a newline (\n)
90
+ /// or carriage return (\r) is found.
95
91
Stdout ( Buffer ) ,
96
92
97
- /// An error happened waiting for the command to finish or converting
98
- /// the stdout/stderr bytes to a UTF-8 string.
93
+ /// Raw or line-buffered stderr output. If configured for raw output,
94
+ /// all bytes written to stderr. Otherwise, bytes until a newline (\n)
95
+ /// or carriage return (\r) is found.
96
+ Stderr ( Buffer ) ,
97
+
98
+ /// An error occurred waiting for the child process to finish.
99
99
Error ( String ) ,
100
100
101
- /// Command process terminated.
101
+ /// Child process terminated.
102
102
Terminated ( ExitStatus ) ,
103
103
}
104
104
@@ -107,7 +107,7 @@ pub enum CommandEvent {
107
107
pub struct ChildProcess {
108
108
inner : Arc < SharedChild > ,
109
109
stdin_writer : PipeWriter ,
110
- rx : mpsc:: Receiver < CommandEvent > ,
110
+ rx : mpsc:: Receiver < ChildProcessEvent > ,
111
111
}
112
112
113
113
impl ChildProcess {
@@ -129,7 +129,7 @@ impl ChildProcess {
129
129
}
130
130
131
131
/// Returns a channel of events from the child process.
132
- pub fn events ( & mut self ) -> & mut mpsc:: Receiver < CommandEvent > {
132
+ pub fn events ( & mut self ) -> & mut mpsc:: Receiver < ChildProcessEvent > {
133
133
& mut self . rx
134
134
}
135
135
}
@@ -140,16 +140,11 @@ pub struct ExitStatus {
140
140
/// Exit code of the process.
141
141
pub code : Option < i32 > ,
142
142
143
- /// If the process was terminated by a signal, represents that signal.
144
- pub signal : Option < i32 > ,
145
- }
143
+ /// Whether the process exited with a zero exit code.
144
+ pub success : bool ,
146
145
147
- impl ExitStatus {
148
- /// Returns true if exit status is zero. Signal termination is not
149
- /// considered a success, and success is defined as a zero exit status.
150
- pub fn success ( & self ) -> bool {
151
- self . code == Some ( 0 )
152
- }
146
+ /// Termination signal if process was killed.
147
+ pub signal : Option < i32 > ,
153
148
}
154
149
155
150
/// The output of a finished process.
@@ -159,10 +154,10 @@ pub struct ShellExecOutput {
159
154
#[ serde( flatten) ]
160
155
pub status : ExitStatus ,
161
156
162
- /// The data that the process wrote to stdout.
157
+ /// The buffer that the process wrote to stdout.
163
158
pub stdout : Buffer ,
164
159
165
- /// The data that the process wrote to stderr.
160
+ /// The buffer that the process wrote to stderr.
166
161
pub stderr : Buffer ,
167
162
}
168
163
@@ -182,7 +177,7 @@ impl Shell {
182
177
/// Shell::exec("echo", &["Hello!"], &CommandOptions::default())
183
178
/// .await
184
179
/// .unwrap();
185
- /// assert!(output.status.success() );
180
+ /// assert!(output.status.success);
186
181
/// assert_eq!(output.stdout.as_str().unwrap(), "Hello!");
187
182
/// ```
188
183
pub async fn exec < I , S > (
@@ -202,16 +197,16 @@ impl Shell {
202
197
203
198
while let Some ( event) = child. events ( ) . recv ( ) . await {
204
199
match event {
205
- CommandEvent :: Terminated ( exit_status) => {
200
+ ChildProcessEvent :: Terminated ( exit_status) => {
206
201
status = exit_status;
207
202
}
208
- CommandEvent :: Stdout ( line) => {
203
+ ChildProcessEvent :: Stdout ( line) => {
209
204
stdout. push ( line) ?;
210
205
}
211
- CommandEvent :: Stderr ( line) => {
206
+ ChildProcessEvent :: Stderr ( line) => {
212
207
stderr. push ( line) ?;
213
208
}
214
- CommandEvent :: Error ( _) => { }
209
+ ChildProcessEvent :: Error ( _) => { }
215
210
}
216
211
}
217
212
@@ -232,7 +227,7 @@ impl Shell {
232
227
/// Shell::status("echo", ["Hello!"], CommandOptions::default())
233
228
/// .await
234
229
/// .unwrap();
235
- /// assert!(status.success() );
230
+ /// assert!(status.success);
236
231
/// ```
237
232
pub async fn status < I , S > (
238
233
& self ,
@@ -247,7 +242,7 @@ impl Shell {
247
242
let mut child = Self :: spawn ( program, args, options) ?;
248
243
249
244
while let Some ( event) = child. events ( ) . recv ( ) . await {
250
- if let CommandEvent :: Terminated ( status) = event {
245
+ if let ChildProcessEvent :: Terminated ( status) = event {
251
246
return Ok ( status) ;
252
247
}
253
248
}
@@ -307,15 +302,15 @@ impl Shell {
307
302
tx. clone ( ) ,
308
303
guard. clone ( ) ,
309
304
stdout_reader,
310
- CommandEvent :: Stdout ,
305
+ ChildProcessEvent :: Stdout ,
311
306
options. encoding . clone ( ) ,
312
307
) ;
313
308
314
309
Self :: spawn_pipe_reader (
315
310
tx. clone ( ) ,
316
311
guard. clone ( ) ,
317
312
stderr_reader,
318
- CommandEvent :: Stderr ,
313
+ ChildProcessEvent :: Stderr ,
319
314
options. encoding . clone ( ) ,
320
315
) ;
321
316
@@ -324,14 +319,15 @@ impl Shell {
324
319
let _lock = guard. write ( ) . unwrap ( ) ;
325
320
326
321
let event = match status {
327
- Ok ( status) => CommandEvent :: Terminated ( ExitStatus {
322
+ Ok ( status) => ChildProcessEvent :: Terminated ( ExitStatus {
328
323
code : status. code ( ) ,
324
+ success : status. code ( ) . is_some_and ( |code| code == 0 ) ,
329
325
#[ cfg( windows) ]
330
326
signal : None ,
331
327
#[ cfg( unix) ]
332
328
signal : status. signal ( ) ,
333
329
} ) ,
334
- Err ( err) => CommandEvent :: Error ( err. to_string ( ) ) ,
330
+ Err ( err) => ChildProcessEvent :: Error ( err. to_string ( ) ) ,
335
331
} ;
336
332
337
333
let _ = tx. blocking_send ( event) ;
@@ -379,20 +375,19 @@ impl Shell {
379
375
/// Spawns a thread to read from stdout/stderr and emit the output
380
376
/// through a channel.
381
377
fn spawn_pipe_reader < F > (
382
- tx : mpsc:: Sender < CommandEvent > ,
378
+ tx : mpsc:: Sender < ChildProcessEvent > ,
383
379
guard : Arc < RwLock < ( ) > > ,
384
380
pipe : os_pipe:: PipeReader ,
385
381
wrapper : F ,
386
382
encoding : Encoding ,
387
383
) where
388
- F : Fn ( Buffer ) -> CommandEvent + Send + Copy + ' static ,
384
+ F : Fn ( Buffer ) -> ChildProcessEvent + Send + Copy + ' static ,
389
385
{
390
386
spawn ( move || {
391
387
let _lock = guard. read ( ) . unwrap ( ) ;
392
388
let mut reader = StdoutReader :: new ( pipe, encoding) ;
393
389
394
390
while let Ok ( Some ( buffer) ) = reader. read_next ( ) {
395
- println ! ( "buffer: {:?}" , buffer) ;
396
391
if tx. blocking_send ( wrapper ( buffer) ) . is_err ( ) {
397
392
break ;
398
393
}
@@ -415,7 +410,7 @@ mod tests {
415
410
. await
416
411
. unwrap ( ) ;
417
412
418
- assert ! ( output. status. success( ) ) ;
413
+ assert ! ( output. status. success) ;
419
414
assert ! ( output. stderr. as_str( ) . unwrap( ) . is_empty( ) ) ;
420
415
assert ! ( output. stdout. as_str( ) . unwrap( ) . contains( "hello world" ) ) ;
421
416
}
@@ -433,7 +428,7 @@ mod tests {
433
428
. await
434
429
. unwrap ( ) ;
435
430
436
- assert ! ( !output. status. success( ) ) ;
431
+ assert ! ( !output. status. success) ;
437
432
assert ! ( !output. stderr. as_str( ) . unwrap( ) . is_empty( ) ) ;
438
433
}
439
434
@@ -454,12 +449,12 @@ mod tests {
454
449
let mut saw_stdout = false ;
455
450
while let Some ( event) = child. events ( ) . recv ( ) . await {
456
451
match event {
457
- CommandEvent :: Stdout ( Buffer :: Raw ( bytes) ) => {
452
+ ChildProcessEvent :: Stdout ( Buffer :: Raw ( bytes) ) => {
458
453
assert ! ( !bytes. is_empty( ) ) ;
459
454
saw_stdout = true ;
460
455
}
461
- CommandEvent :: Terminated ( status) => {
462
- assert ! ( status. success( ) ) ;
456
+ ChildProcessEvent :: Terminated ( status) => {
457
+ assert ! ( status. success) ;
463
458
}
464
459
_ => { }
465
460
}
0 commit comments