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 pub command: String,
11
12 pub id: Option<String>,
14
15 pub name: Option<String>,
17
18 pub toolchain: Option<Version>,
20
21 #[setters(skip)]
23 pub args: Vec<String>,
24}
25
26impl Cargo {
27 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 pub fn nightly(mut self) -> Self {
40 self.toolchain = Some(Version::Nightly);
41 self
42 }
43
44 pub fn args<T: ToString>(mut self, args: T) -> Self {
47 self.args = vec![args.to_string()];
48 self
49 }
50
51 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 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}