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) -> Self {
29        Self {
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
63impl From<Cargo> for Step<Run> {
64    fn from(value: Cargo) -> Self {
65        let mut command = vec!["cargo".to_string()];
66
67        if let Some(toolchain) = value.toolchain {
68            command.push(format!("+{toolchain}"));
69        }
70
71        command.push(value.command.clone());
72
73        // Extend the command with non-empty arguments
74        command.extend(
75            value
76                .args
77                .into_iter()
78                .map(|arg| arg.trim().to_string())
79                .filter(|arg| !arg.is_empty()),
80        );
81
82        let mut step = Step::new(format!("Cargo {}", value.command)).run(command.join(" "));
83
84        if let Some(id) = value.id {
85            step = step.id(id);
86        }
87
88        if let Some(name) = value.name {
89            step = step.name(name);
90        }
91
92        step
93    }
94}