cmdstruct/
lib.rs

1#![doc = include_str!("../README.md")]
2
3pub use cmdstruct_macros::Command;
4
5/// A trait representing a particular command
6pub trait Command {
7
8    /// Generate a spawnable command
9    fn command(&self) -> std::process::Command;
10
11}
12
13/// A trait representing an argument to a command
14pub trait Arg {
15
16    /// Append as positional argument
17    fn append_arg(&self, command: &mut std::process::Command);
18
19    /// Append as an option
20    fn append_option(&self, name: &str, command: &mut std::process::Command) {
21        self.append_arg(command.arg(name));
22    }
23}
24
25macro_rules! format_impl {
26    ($($ty:ident) *) => {
27        $(
28        impl Arg for $ty {
29            fn append_arg(&self, command: &mut std::process::Command)
30            {
31                command.arg(&format!("{}", self));
32            }
33        }
34        )*
35    }
36}
37
38format_impl!(u8 u16 u32 u64 usize);
39format_impl!(i8 i16 i32 i64 isize);
40format_impl!(char String);
41format_impl!(f32 f64);
42
43impl<T> Arg for Option<T>
44where
45    T: Arg,
46{
47    fn append_arg(&self, command: &mut std::process::Command) {
48        match self {
49            Some(arg) => arg.append_arg(command),
50            None => {}
51        }
52    }
53
54    fn append_option(&self, name: &str, command: &mut std::process::Command) {
55        match self {
56            Some(arg) => arg.append_option(name, command),
57            None => {}
58        }
59    }
60}
61
62impl<T> Arg for Vec<T>
63where
64    T: Arg,
65{
66    fn append_arg(&self, command: &mut std::process::Command) {
67        for argument in self {
68            argument.append_arg(command);
69        }
70    }
71
72    fn append_option(&self, name: &str, command: &mut std::process::Command) {
73        for argument in self {
74            argument.append_option(name, command);
75        }
76    }
77}