shellfn_core/execute/
void.rs

1use crate::error::{Error, NeverError};
2use crate::utils::{spawn, PANIC_MSG};
3use std::ffi::OsStr;
4use std::process::{Child, Output};
5
6/// Executes command with args and environment variables, ignores output
7/// * On invalid command: do nothing
8/// * On error exit code: do nothing
9/// * On parsing failure: N/A
10/// * Possible errors: N/A
11///
12/// Designed for
13/// ```rust
14/// use shellfn::shell;
15///
16/// #[shell(no_panic)]
17/// fn command() {
18///     "echo Hello, world"
19/// }
20///
21/// command()
22/// ```
23pub fn execute_void_nopanic<TArg, TEnvKey, TEnvVal>(
24    cmd: impl AsRef<OsStr>,
25    args: impl IntoIterator<Item = TArg>,
26    envs: impl IntoIterator<Item = (TEnvKey, TEnvVal)>,
27) where
28    TArg: AsRef<OsStr>,
29    TEnvKey: AsRef<OsStr>,
30    TEnvVal: AsRef<OsStr>,
31{
32    let _ = spawn(cmd, args, envs).and_then(Child::wait_with_output);
33}
34
35/// Executes command with args and environment variables, ignores output
36/// * On invalid command: panic
37/// * On error exit code: panic
38/// * On parsing failure: N/A
39/// * Possible errors: N/A
40///
41/// Designed for
42/// ```rust
43/// use shellfn::shell;
44///
45/// #[shell]
46/// fn command() {
47///     "echo Hello, world"
48/// }
49///
50/// command()
51/// ```
52pub fn execute_void_panic<TArg, TEnvKey, TEnvVal>(
53    cmd: impl AsRef<OsStr>,
54    args: impl IntoIterator<Item = TArg>,
55    envs: impl IntoIterator<Item = (TEnvKey, TEnvVal)>,
56) where
57    TArg: AsRef<OsStr>,
58    TEnvKey: AsRef<OsStr>,
59    TEnvVal: AsRef<OsStr>,
60{
61    let output = spawn(cmd, args, envs)
62        .and_then(Child::wait_with_output)
63        .expect(PANIC_MSG);
64
65    if !output.status.success() {
66        panic!("{}", PANIC_MSG)
67    }
68}
69
70/// Executes command with args and environment variables, ignores output
71/// * On invalid command: return error
72/// * On error exit code: return error
73/// * On parsing failure: N/A
74/// * Possible errors: ProcessNotSpawned, WaitFailed, ProcessFailed (stdout and stderr always empty)
75///
76/// Designed for
77/// ```rust
78/// use shellfn::shell;
79///
80/// #[shell]
81/// fn command() -> Result<(), Box<Error>> {
82///     sleep 5
83/// }
84///
85/// command()
86/// ```
87pub fn execute_void_result<TArg, TEnvKey, TEnvVal, TError>(
88    cmd: impl AsRef<OsStr>,
89    args: impl IntoIterator<Item = TArg>,
90    envs: impl IntoIterator<Item = (TEnvKey, TEnvVal)>,
91) -> Result<(), TError>
92where
93    TArg: AsRef<OsStr>,
94    TEnvKey: AsRef<OsStr>,
95    TEnvVal: AsRef<OsStr>,
96    TError: From<Error<NeverError>>,
97{
98    let mut process = spawn(cmd, args, envs).map_err(Error::ProcessNotSpawned)?;
99    let status = process.wait().map_err(Error::WaitFailed)?;
100
101    if !status.success() {
102        Err(Error::ProcessFailed(Output {
103            status,
104            stdout: Vec::new(),
105            stderr: Vec::new(),
106        })
107        .into())
108    } else {
109        Ok(())
110    }
111}