@@ -29,20 +29,58 @@ use crate::{
29
29
#[ derive( Debug ) ]
30
30
pub struct Command {
31
31
cmd : StdCommand ,
32
- stdin : Option < Box < [ u8 ] > > ,
32
+ // Convience for providing a quick stdin buffer.
33
+ stdin_buf : Option < Box < [ u8 ] > > ,
34
+
35
+ // Configurations for child process's std{in,out,err} handles.
36
+ stdin : Option < Stdio > ,
37
+ stdout : Option < Stdio > ,
38
+ stderr : Option < Stdio > ,
39
+
33
40
drop_bomb : DropBomb ,
34
41
}
35
42
36
43
impl Command {
37
44
#[ track_caller]
38
45
pub fn new < P : AsRef < OsStr > > ( program : P ) -> Self {
39
46
let program = program. as_ref ( ) ;
40
- Self { cmd : StdCommand :: new ( program) , stdin : None , drop_bomb : DropBomb :: arm ( program) }
47
+ Self {
48
+ cmd : StdCommand :: new ( program) ,
49
+ stdin_buf : None ,
50
+ drop_bomb : DropBomb :: arm ( program) ,
51
+ stdin : None ,
52
+ stdout : None ,
53
+ stderr : None ,
54
+ }
55
+ }
56
+
57
+ /// Specify a stdin input buffer. This is a convenience helper,
58
+ pub fn stdin_buf < I : AsRef < [ u8 ] > > ( & mut self , input : I ) -> & mut Self {
59
+ self . stdin_buf = Some ( input. as_ref ( ) . to_vec ( ) . into_boxed_slice ( ) ) ;
60
+ self
61
+ }
62
+
63
+ /// Configuration for the child process’s standard input (stdin) handle.
64
+ ///
65
+ /// See [`std::process::Command::stdin`].
66
+ pub fn stdin < T : Into < Stdio > > ( & mut self , cfg : T ) -> & mut Self {
67
+ self . stdin = Some ( cfg. into ( ) ) ;
68
+ self
69
+ }
70
+
71
+ /// Configuration for the child process’s standard output (stdout) handle.
72
+ ///
73
+ /// See [`std::process::Command::stdout`].
74
+ pub fn stdout < T : Into < Stdio > > ( & mut self , cfg : T ) -> & mut Self {
75
+ self . stdout = Some ( cfg. into ( ) ) ;
76
+ self
41
77
}
42
78
43
- /// Specify a stdin input
44
- pub fn stdin < I : AsRef < [ u8 ] > > ( & mut self , input : I ) -> & mut Self {
45
- self . stdin = Some ( input. as_ref ( ) . to_vec ( ) . into_boxed_slice ( ) ) ;
79
+ /// Configuration for the child process’s standard error (stderr) handle.
80
+ ///
81
+ /// See [`std::process::Command::stderr`].
82
+ pub fn stderr < T : Into < Stdio > > ( & mut self , cfg : T ) -> & mut Self {
83
+ self . stderr = Some ( cfg. into ( ) ) ;
46
84
self
47
85
}
48
86
@@ -105,6 +143,8 @@ impl Command {
105
143
}
106
144
107
145
/// Run the constructed command and assert that it is successfully run.
146
+ ///
147
+ /// By default, std{in,out,err} are [`Stdio::piped()`].
108
148
#[ track_caller]
109
149
pub fn run ( & mut self ) -> CompletedProcess {
110
150
let output = self . command_output ( ) ;
@@ -115,6 +155,8 @@ impl Command {
115
155
}
116
156
117
157
/// Run the constructed command and assert that it does not successfully run.
158
+ ///
159
+ /// By default, std{in,out,err} are [`Stdio::piped()`].
118
160
#[ track_caller]
119
161
pub fn run_fail ( & mut self ) -> CompletedProcess {
120
162
let output = self . command_output ( ) ;
@@ -124,10 +166,10 @@ impl Command {
124
166
output
125
167
}
126
168
127
- /// Run the command but do not check its exit status.
128
- /// Only use if you explicitly don't care about the exit status.
129
- /// Prefer to use [`Self::run`] and [`Self::run_fail`]
130
- /// whenever possible.
169
+ /// Run the command but do not check its exit status. Only use if you explicitly don't care
170
+ /// about the exit status.
171
+ ///
172
+ /// Prefer to use [`Self::run`] and [`Self::run_fail`] whenever possible.
131
173
#[ track_caller]
132
174
pub fn run_unchecked ( & mut self ) -> CompletedProcess {
133
175
self . command_output ( )
@@ -137,11 +179,11 @@ impl Command {
137
179
fn command_output ( & mut self ) -> CompletedProcess {
138
180
self . drop_bomb . defuse ( ) ;
139
181
// let's make sure we piped all the input and outputs
140
- self . cmd . stdin ( Stdio :: piped ( ) ) ;
141
- self . cmd . stdout ( Stdio :: piped ( ) ) ;
142
- self . cmd . stderr ( Stdio :: piped ( ) ) ;
182
+ self . cmd . stdin ( self . stdin . take ( ) . unwrap_or ( Stdio :: piped ( ) ) ) ;
183
+ self . cmd . stdout ( self . stdout . take ( ) . unwrap_or ( Stdio :: piped ( ) ) ) ;
184
+ self . cmd . stderr ( self . stderr . take ( ) . unwrap_or ( Stdio :: piped ( ) ) ) ;
143
185
144
- let output = if let Some ( input) = & self . stdin {
186
+ let output = if let Some ( input) = & self . stdin_buf {
145
187
let mut child = self . cmd . spawn ( ) . unwrap ( ) ;
146
188
147
189
{
0 commit comments