gh_workflow/
cargo.rs

1use derive_setters::Setters;
2
3use crate::toolchain::Version;
4use crate::{Run, Step};
5
6#[derive(Clone, Setters)]
7#[setters(strip_option, into)]
8pub struct Cargo {
9    /// The command to be executed for eg: fmt, clippy, build, test, etc.
10    pub command: String,
11
12    /// The unique identifier of the Step.
13    pub id: Option<String>,
14
15    /// Name of the Step
16    pub name: Option<String>,
17
18    /// Toolchain to be used for example `+nightly`.
19    pub toolchain: Option<Version>,
20
21    /// Arguments to be passed to the cargo command.
22    #[setters(skip)]
23    pub args: Vec<String>,
24}
25
26impl Cargo {
27    /// Creates a new `Cargo` instance with the specified command.
28    pub fn new<T: ToString>(cmd: T) -> Cargo {
29        Cargo {
30            command: cmd.to_string(),
31            id: Default::default(),
32            name: Default::default(),
33            toolchain: Default::default(),
34            args: Default::default(),
35        }
36    }
37
38    /// Sets the toolchain to nightly.
39    pub fn nightly(mut self) -> Self {
40        self.toolchain = Some(Version::Nightly);
41        self
42    }
43
44    /// Sets the arguments for the cargo command. If arguments are already set,
45    /// it will be overwritten.
46    pub fn args<T: ToString>(mut self, args: T) -> Self {
47        self.args = vec![args.to_string()];
48        self
49    }
50
51    /// Adds additional arguments to the cargo command.
52    pub fn add_args<T: ToString>(mut self, args: T) -> Self {
53        self.args.extend(
54            args.to_string()
55                .split_whitespace()
56                .map(|s| s.to_string())
57                .collect::<Vec<_>>(),
58        );
59        self
60    }
61
62    /// Adds the arguments to the cargo command when a condition is met.
63    pub fn add_args_when<T: ToString>(self, when: bool, args: T) -> Self {
64        if when {
65            self.add_args(args)
66        } else {
67            self
68        }
69    }
70}
71
72impl From<Cargo> for Step<Run> {
73    fn from(value: Cargo) -> Self {
74        let mut command = vec!["cargo".to_string()];
75
76        if let Some(toolchain) = value.toolchain {
77            command.push(format!("+{}", toolchain));
78        }
79
80        command.push(value.command);
81
82        // Extend the command with non-empty arguments
83        command.extend(
84            value
85                .args
86                .into_iter()
87                .map(|arg| arg.trim().to_string())
88                .filter(|arg| !arg.is_empty()),
89        );
90
91        let mut step = Step::run(command.join(" "));
92
93        if let Some(id) = value.id {
94            step = step.id(id);
95        }
96
97        if let Some(name) = value.name {
98            step = step.name(name);
99        }
100
101        step
102    }
103}