wasm_opt/
fake_command.rs

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
7/// Like [`std::process::Command`] but args are iterable in old versions of Rust.
8pub 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    >, // omg
115}
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}