command_error/
command_display.rs

1use std::borrow::Cow;
2use std::fmt::Display;
3
4#[cfg(doc)]
5use std::process::Command;
6
7use dyn_clone::DynClone;
8
9#[cfg(doc)]
10use crate::Utf8ProgramAndArgs;
11
12/// A [`Command`] that can be [`Display`]ed.
13///
14/// The command's program and arguments are provided as strings, which may contain � U+FFFD
15/// REPLACEMENT CHARACTER if the program or arguments cannot be decoded as UTF-8.
16///
17/// The [`Display`] implementation in [`Utf8ProgramAndArgs`] additionally performs shell quoting on
18/// the command's program and args.
19pub trait CommandDisplay: Display + DynClone {
20    /// The command's program name, decoded as UTF-8.
21    ///
22    /// ```
23    /// # use std::process::Command;
24    /// # use command_error::Utf8ProgramAndArgs;
25    /// # use command_error::CommandDisplay;
26    /// let command = Command::new("echo");
27    /// let displayed: Utf8ProgramAndArgs = (&command).into();
28    /// assert_eq!(
29    ///     displayed.program(),
30    ///     "echo",
31    /// );
32    /// ```
33    fn program(&self) -> Cow<'_, str>;
34
35    /// The command's program name, shell-quoted.
36    ///
37    /// ```
38    /// # use std::process::Command;
39    /// # use command_error::Utf8ProgramAndArgs;
40    /// # use command_error::CommandDisplay;
41    /// let command = Command::new("ooga booga");
42    /// let displayed: Utf8ProgramAndArgs = (&command).into();
43    /// assert_eq!(
44    ///     displayed.program_quoted(),
45    ///     "'ooga booga'",
46    /// );
47    /// ```
48    fn program_quoted(&self) -> Cow<'_, str> {
49        Cow::Owned(shell_words::quote(&self.program()).into_owned())
50    }
51
52    /// The command's arguments, decoded as UTF-8.
53    ///
54    /// ```
55    /// # use std::process::Command;
56    /// # use command_error::Utf8ProgramAndArgs;
57    /// # use command_error::CommandDisplay;
58    /// let mut command = Command::new("echo");
59    /// command.arg("puppy doggy");
60    /// let displayed: Utf8ProgramAndArgs = (&command).into();
61    /// assert_eq!(
62    ///     displayed.args().collect::<Vec<_>>(),
63    ///     vec!["puppy doggy"],
64    /// );
65    /// ```
66    fn args(&self) -> Box<dyn Iterator<Item = Cow<'_, str>> + '_>;
67}