term_detect/
cmdtrait.rs

1use crate::{get_terminal, DetectionError, Terminal};
2use std::ffi::OsStr;
3use std::process::Command;
4
5#[cfg(target_os = "linux")]
6fn rawstrcmd(cmd: &Command) -> String {
7    format!("{:?}", cmd)
8}
9
10#[cfg(target_os = "linux")]
11fn strcmd(cmd: &Command) -> String {
12    format!("bash -c {:?}", rawstrcmd(cmd))
13}
14
15/// Allows a `Command` to be executed in a terminal
16pub trait InTerminal {
17    fn in_terminal(&self, term: Terminal) -> Self;
18    fn in_terminal_args<I, S>(&self, term: Terminal, args: I) -> Self
19    where
20        I: IntoIterator<Item = S>,
21        S: AsRef<OsStr>;
22}
23
24impl InTerminal for Command {
25    fn in_terminal(&self, term: Terminal) -> Self {
26        let mut cmd = Command::new(term);
27        cmd.arg("-e").arg(strcmd(self));
28        cmd
29    }
30    fn in_terminal_args<I, S>(&self, term: Terminal, args: I) -> Self
31    where
32        I: IntoIterator<Item = S>,
33        S: AsRef<OsStr>,
34    {
35        let mut cmd = Command::new(term);
36        cmd.args(args).arg("-e").arg(strcmd(self));
37        cmd
38    }
39}
40
41/// Allows a `Command` to be executed in a terminal (which is automatically detected)
42pub trait InTerminalAuto: InTerminal
43where
44    Self: Sized,
45{
46    fn in_terminal(&self) -> Result<Self, DetectionError>;
47    fn in_terminal_args<I, S>(&self, args: I) -> Result<Self, DetectionError>
48    where
49        I: IntoIterator<Item = S>,
50        S: AsRef<OsStr>;
51}
52
53impl InTerminalAuto for Command {
54    fn in_terminal(&self) -> Result<Self, DetectionError> {
55        Ok(InTerminal::in_terminal(self, get_terminal()?))
56    }
57    fn in_terminal_args<I, S>(&self, args: I) -> Result<Self, DetectionError>
58    where
59        I: IntoIterator<Item = S>,
60        S: AsRef<OsStr>,
61    {
62        Ok(InTerminal::in_terminal_args(self, get_terminal()?, args))
63    }
64}