Skip to main content

util/
command.rs

1use std::ffi::OsStr;
2#[cfg(not(target_os = "macos"))]
3use std::path::Path;
4
5#[cfg(target_os = "macos")]
6mod darwin;
7
8#[cfg(target_os = "macos")]
9pub use darwin::{Child, Command, Stdio};
10
11#[cfg(target_os = "windows")]
12const CREATE_NO_WINDOW: u32 = 0x0800_0000_u32;
13
14pub fn new_command(program: impl AsRef<OsStr>) -> Command {
15    Command::new(program)
16}
17
18#[cfg(target_os = "windows")]
19pub fn new_std_command(program: impl AsRef<OsStr>) -> std::process::Command {
20    use std::os::windows::process::CommandExt;
21
22    let mut command = std::process::Command::new(program);
23    command.creation_flags(CREATE_NO_WINDOW);
24    command
25}
26
27#[cfg(not(target_os = "windows"))]
28pub fn new_std_command(program: impl AsRef<OsStr>) -> std::process::Command {
29    std::process::Command::new(program)
30}
31
32#[cfg(not(target_os = "macos"))]
33pub type Child = smol::process::Child;
34
35#[cfg(not(target_os = "macos"))]
36pub use std::process::Stdio;
37
38#[cfg(not(target_os = "macos"))]
39#[derive(Debug)]
40pub struct Command(smol::process::Command);
41
42#[cfg(not(target_os = "macos"))]
43impl Command {
44    #[inline]
45    pub fn new(program: impl AsRef<OsStr>) -> Self {
46        #[cfg(target_os = "windows")]
47        {
48            use smol::process::windows::CommandExt;
49            let mut cmd = smol::process::Command::new(program);
50            cmd.creation_flags(CREATE_NO_WINDOW);
51            Self(cmd)
52        }
53        #[cfg(not(target_os = "windows"))]
54        Self(smol::process::Command::new(program))
55    }
56
57    pub fn arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
58        self.0.arg(arg);
59        self
60    }
61
62    pub fn args<I, S>(&mut self, args: I) -> &mut Self
63    where
64        I: IntoIterator<Item = S>,
65        S: AsRef<OsStr>,
66    {
67        self.0.args(args);
68        self
69    }
70
71    pub fn get_args(&self) -> impl Iterator<Item = &OsStr> {
72        self.0.get_args()
73    }
74
75    pub fn env(&mut self, key: impl AsRef<OsStr>, val: impl AsRef<OsStr>) -> &mut Self {
76        self.0.env(key, val);
77        self
78    }
79
80    pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Self
81    where
82        I: IntoIterator<Item = (K, V)>,
83        K: AsRef<OsStr>,
84        V: AsRef<OsStr>,
85    {
86        self.0.envs(vars);
87        self
88    }
89
90    pub fn env_remove(&mut self, key: impl AsRef<OsStr>) -> &mut Self {
91        self.0.env_remove(key);
92        self
93    }
94
95    pub fn env_clear(&mut self) -> &mut Self {
96        self.0.env_clear();
97        self
98    }
99
100    pub fn current_dir(&mut self, dir: impl AsRef<Path>) -> &mut Self {
101        self.0.current_dir(dir);
102        self
103    }
104
105    pub fn stdin(&mut self, cfg: impl Into<Stdio>) -> &mut Self {
106        self.0.stdin(cfg.into());
107        self
108    }
109
110    pub fn stdout(&mut self, cfg: impl Into<Stdio>) -> &mut Self {
111        self.0.stdout(cfg.into());
112        self
113    }
114
115    pub fn stderr(&mut self, cfg: impl Into<Stdio>) -> &mut Self {
116        self.0.stderr(cfg.into());
117        self
118    }
119
120    pub fn kill_on_drop(&mut self, kill_on_drop: bool) -> &mut Self {
121        self.0.kill_on_drop(kill_on_drop);
122        self
123    }
124
125    pub fn spawn(&mut self) -> std::io::Result<Child> {
126        self.0.spawn()
127    }
128
129    pub async fn output(&mut self) -> std::io::Result<std::process::Output> {
130        self.0.output().await
131    }
132
133    pub async fn status(&mut self) -> std::io::Result<std::process::ExitStatus> {
134        self.0.status().await
135    }
136
137    pub fn get_program(&self) -> &OsStr {
138        self.0.get_program()
139    }
140}