1use paste::paste;
2
3macro_rules! cargo_command {
4 ($command: ident) => {
5 paste! {
6 pub mod [<$command:lower>] {
7 use std::ops::{Deref, DerefMut};
8 use std::path::PathBuf;
9 use std::process::{self, Command};
10
11 use anyhow::{Context, Result};
12 use clap::Parser;
13
14 use crate::options::XWinOptions;
15
16 #[derive(Clone, Debug, Default, Parser)]
17 #[command(
18 display_order = 1,
19 about = "Run cargo " $command:lower " command",
20 after_help = "Run `cargo help " $command:lower "` for more detailed information."
21 )]
22 pub struct $command {
23 #[command(flatten)]
24 pub cargo: cargo_options::$command,
25
26 #[command(flatten)]
27 pub xwin: XWinOptions,
28 }
29
30 impl $command {
31 #[allow(clippy::field_reassign_with_default)]
33 pub fn new(manifest_path: Option<PathBuf>) -> Self {
34 let mut build = Self::default();
35 build.manifest_path = manifest_path;
36 build
37 }
38
39 pub fn execute(&self) -> Result<()> {
41 let current_command = stringify!([<$command:lower>]);
42 let mut build = self.build_command()?;
43 let mut child = build.spawn().with_context(|| format!("Failed to run cargo {current_command}"))?;
44 let status = child.wait().expect(&format!("Failed to wait on cargo {current_command} process"));
45 if !status.success() {
46 process::exit(status.code().unwrap_or(1));
47 }
48 Ok(())
49 }
50
51 pub fn build_command(&self) -> Result<Command> {
53 let mut build = self.cargo.command();
54 self.xwin.apply_command_env(
55 self.manifest_path.as_deref(),
56 &self.cargo.common,
57 &mut build,
58 )?;
59 Ok(build)
60 }
61 }
62
63 impl Deref for $command {
64 type Target = cargo_options::$command;
65
66 fn deref(&self) -> &Self::Target {
67 &self.cargo
68 }
69 }
70
71 impl DerefMut for $command {
72 fn deref_mut(&mut self) -> &mut Self::Target {
73 &mut self.cargo
74 }
75 }
76
77 impl From<cargo_options::$command> for $command {
78 fn from(cargo: cargo_options::$command) -> Self {
79 Self {
80 cargo,
81 ..Default::default()
82 }
83 }
84 }
85
86 }
87 }
88 };
89}
90
91cargo_command!(Build);
92cargo_command!(Check);
93cargo_command!(Clippy);
94cargo_command!(Doc);
95cargo_command!(Rustc);