Skip to main content

cargo_xwin/
macros.rs

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                    /// Create a new build from manifest path
32                    #[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                    /// Execute cargo command
40                    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                    /// Generate cargo subcommand
52                    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);