File tree Expand file tree Collapse file tree 3 files changed +77
-0
lines changed Expand file tree Collapse file tree 3 files changed +77
-0
lines changed Original file line number Diff line number Diff line change @@ -680,6 +680,40 @@ impl Command {
680680 self
681681 }
682682
683+ /// Sets the argument at index to a new value.
684+ ///
685+ /// When one wants to restart a Command again with different
686+ /// arguments the argument list can to be cleared first.
687+ ///
688+ /// # Examples
689+ ///
690+ /// Basic usage:
691+ ///
692+ /// ```no_run
693+ /// #![feature(mutate_command_args)]
694+ /// use std::process::Command;
695+ ///
696+ /// // Prepare a command
697+ /// let mut command = Command::new("ls");
698+ /// command.args(["-l", "-a", "FILE"]);
699+ ///
700+ /// // Run it with mutated 3rd parameter
701+ /// ["foo", "bar", "baz"].iter()
702+ /// .for_each(
703+ /// |file| {
704+ /// command
705+ /// .arg_set(3, file)
706+ /// .spawn()
707+ /// .unwrap();
708+ /// }
709+ /// );
710+ /// ```
711+ #[ unstable( feature = "mutate_command_args" , issue = "87379" ) ]
712+ pub fn arg_set < S : AsRef < OsStr > > ( & mut self , index : usize , value : S ) -> & mut Command {
713+ self . inner . arg_set ( index, value. as_ref ( ) ) ;
714+ self
715+ }
716+
683717 /// Inserts or updates an environment variable mapping.
684718 ///
685719 /// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
Original file line number Diff line number Diff line change @@ -237,6 +237,42 @@ fn test_args_clear() {
237237 assert_eq ! ( stderr, Vec :: new( ) ) ;
238238}
239239
240+ #[ test]
241+ fn test_arg_set ( ) {
242+ let mut prog = Command :: new ( "echo" ) ;
243+
244+ if cfg ! ( target_os = "windows" ) {
245+ prog. args ( & [ "/C" , "echo set_me" ] )
246+ } else {
247+ prog. arg ( "set_me" )
248+ } ;
249+
250+ if cfg ! ( target_os = "windows" ) {
251+ prog. arg_set ( 2 , "echo hello" ) ;
252+ } else {
253+ prog. arg_set ( 1 , "hello" ) ;
254+ } ;
255+
256+ let Output { status, stdout, stderr } = prog. output ( ) . unwrap ( ) ;
257+ let output_str = str:: from_utf8 ( & stdout) . unwrap ( ) ;
258+
259+ assert ! ( status. success( ) ) ;
260+ assert_eq ! ( output_str. trim( ) . to_string( ) , "hello" ) ;
261+ assert_eq ! ( stderr, Vec :: new( ) ) ;
262+ }
263+
264+ #[ test]
265+ #[ should_panic]
266+ fn test_arg_set_fail ( ) {
267+ let mut prog = Command :: new ( "echo" ) ;
268+
269+ if cfg ! ( target_os = "windows" ) {
270+ prog. arg_set ( 1 , "echo hello" ) ;
271+ } else {
272+ prog. arg_set ( 1 , "hello" ) ;
273+ } ;
274+ }
275+
240276#[ cfg( all( unix, not( target_os = "android" ) ) ) ]
241277pub fn env_cmd ( ) -> Command {
242278 Command :: new ( "env" )
Original file line number Diff line number Diff line change @@ -199,6 +199,13 @@ impl Command {
199199 self . args . truncate ( 1 ) ;
200200 }
201201
202+ pub fn arg_set ( & mut self , index : usize , arg : & OsStr ) {
203+ debug_assert ! ( index >= 1 && index < self . args. len( ) , "Index out of range" ) ;
204+ let arg = os2c ( arg, & mut self . saw_nul ) ;
205+ self . argv . 0 [ index] = arg. as_ptr ( ) ;
206+ self . args [ index] = arg;
207+ }
208+
202209 pub fn cwd ( & mut self , dir : & OsStr ) {
203210 self . cwd = Some ( os2c ( dir, & mut self . saw_nul ) ) ;
204211 }
You can’t perform that action at this time.
0 commit comments