1use std::ffi::{OsStr, OsString};
2use std::io::Result;
3use std::path::Path;
4use std::process::Command as StdCommand;
5use std::process::{Child, ExitStatus, Output, Stdio};
6
7pub struct Command {
9 inner: StdCommand,
10 cached_args: Vec<OsString>,
11}
12
13impl Command {
14 pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
15 Command {
16 inner: StdCommand::new(program),
17 cached_args: vec![],
18 }
19 }
20
21 pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
22 self.cached_args.push(OsString::from(arg.as_ref()));
23 self.inner.arg(arg);
24 self
25 }
26
27 pub fn args<I, S>(&mut self, args: I) -> &mut Command
28 where
29 I: IntoIterator<Item = S>,
30 S: AsRef<OsStr>,
31 {
32 let args: Vec<_> = args.into_iter().collect();
33 self.cached_args
34 .extend(args.iter().map(|arg| OsString::from(arg)));
35 self.inner.args(args);
36 self
37 }
38
39 pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
40 where
41 K: AsRef<OsStr>,
42 V: AsRef<OsStr>,
43 {
44 self.inner.env(key, val);
45 self
46 }
47
48 pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command
49 where
50 I: IntoIterator<Item = (K, V)>,
51 K: AsRef<OsStr>,
52 V: AsRef<OsStr>,
53 {
54 self.inner.envs(vars);
55 self
56 }
57
58 pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
59 self.inner.env_remove(key);
60 self
61 }
62
63 pub fn env_clear(&mut self) -> &mut Command {
64 self.inner.env_clear();
65 self
66 }
67
68 pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command {
69 self.inner.current_dir(dir);
70 self
71 }
72
73 pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
74 self.inner.stdin(cfg);
75 self
76 }
77
78 pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
79 self.inner.stdout(cfg);
80 self
81 }
82
83 pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
84 self.inner.stderr(cfg);
85 self
86 }
87
88 pub fn spawn(&mut self) -> Result<Child> {
89 self.inner.spawn()
90 }
91
92 pub fn output(&mut self) -> Result<Output> {
93 self.inner.output()
94 }
95
96 pub fn status(&mut self) -> Result<ExitStatus> {
97 self.inner.status()
98 }
99
100 pub fn get_args(&self) -> CommandArgs<'_> {
101 CommandArgs {
102 inner: self
103 .cached_args
104 .iter()
105 .map(&|arg: &OsString| arg.as_os_str()),
106 }
107 }
108}
109
110pub struct CommandArgs<'cmd> {
111 inner: std::iter::Map<
112 std::slice::Iter<'cmd, OsString>,
113 &'cmd dyn for<'r> Fn(&'r OsString) -> &'r OsStr,
114 >, }
116
117impl<'cmd> Iterator for CommandArgs<'cmd> {
118 type Item = &'cmd OsStr;
119
120 fn next(&mut self) -> Option<&'cmd OsStr> {
121 self.inner.next()
122 }
123}
124
125impl std::fmt::Debug for Command {
126 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
127 self.inner.fmt(f)
128 }
129}