|
1 | 1 | #![deny(rust_2018_idioms)]
|
2 | 2 | #![forbid(unsafe_code)]
|
3 |
| -#![allow(dead_code)] |
4 | 3 |
|
5 | 4 | use std::ffi::OsString;
|
6 | 5 |
|
7 | 6 | pub struct Prepare {
|
8 | 7 | command: OsString,
|
| 8 | + stdin: std::process::Stdio, |
| 9 | + stdout: std::process::Stdio, |
| 10 | + stderr: std::process::Stdio, |
9 | 11 | use_shell: bool,
|
10 | 12 | }
|
11 | 13 |
|
12 | 14 | mod prepare {
|
13 | 15 | use crate::Prepare;
|
| 16 | + use std::process::Stdio; |
14 | 17 |
|
15 | 18 | /// Builder
|
16 | 19 | impl Prepare {
|
| 20 | + /// If called, the command will not be executed directly, but with `sh`. |
| 21 | + /// |
| 22 | + /// This also allows to pass shell scripts as command, or use commands that contain arguments which are subsequently |
| 23 | + /// parsed by `sh`. |
17 | 24 | pub fn with_shell(mut self) -> Self {
|
18 | 25 | self.use_shell = true;
|
19 | 26 | self
|
20 | 27 | }
|
| 28 | + |
| 29 | + /// Configure the process to use `stdio` for _stdin. |
| 30 | + pub fn stdin(mut self, stdio: Stdio) -> Self { |
| 31 | + self.stdin = stdio; |
| 32 | + self |
| 33 | + } |
| 34 | + /// Configure the process to use `stdio` for _stdout_. |
| 35 | + pub fn stdout(mut self, stdio: Stdio) -> Self { |
| 36 | + self.stdout = stdio; |
| 37 | + self |
| 38 | + } |
| 39 | + /// Configure the process to use `stdio` for _stderr. |
| 40 | + pub fn stderr(mut self, stdio: Stdio) -> Self { |
| 41 | + self.stderr = stdio; |
| 42 | + self |
| 43 | + } |
21 | 44 | }
|
22 | 45 |
|
23 | 46 | /// Finalization
|
24 | 47 | impl Prepare {
|
25 | 48 | pub fn spawn(self) -> std::io::Result<std::process::Child> {
|
26 |
| - todo!("create command and spawn that") |
| 49 | + let mut cmd = if self.use_shell { |
| 50 | + let mut cmd = std::process::Command::new(if cfg!(windows) { "sh" } else { "/bin/sh" }); |
| 51 | + cmd.arg("-c"); |
| 52 | + cmd.arg(self.command); |
| 53 | + cmd |
| 54 | + } else { |
| 55 | + std::process::Command::new(self.command) |
| 56 | + }; |
| 57 | + cmd.stdin(self.stdin).stdout(self.stdout).stderr(self.stderr); |
| 58 | + cmd.spawn() |
27 | 59 | }
|
28 | 60 | }
|
29 | 61 | }
|
30 | 62 |
|
| 63 | +/// Prepare `cmd` for [spawning][Process::spawn()] by configuring it with various builder methods. |
| 64 | +/// |
| 65 | +/// Note that the default IO is configured for typical API usage, that is |
| 66 | +/// |
| 67 | +/// - `stdin` is null |
| 68 | +/// - `stdout` and `stderr` are captured. |
31 | 69 | pub fn prepare(cmd: impl Into<OsString>) -> Prepare {
|
32 | 70 | Prepare {
|
33 | 71 | command: cmd.into(),
|
| 72 | + stdin: std::process::Stdio::null(), |
| 73 | + stdout: std::process::Stdio::piped(), |
| 74 | + stderr: std::process::Stdio::piped(), |
34 | 75 | use_shell: false,
|
35 | 76 | }
|
36 | 77 | }
|
0 commit comments