Skip to main content

cargo_xwin/
bench.rs

1use std::env;
2use std::ops::{Deref, DerefMut};
3use std::path::PathBuf;
4use std::process::{self, Command};
5
6use anyhow::{Context, Result};
7use clap::Parser;
8
9use crate::options::XWinOptions;
10
11/// Execute all benchmarks of a local package
12#[derive(Clone, Debug, Default, Parser)]
13#[command(
14    display_order = 1,
15    after_help = "Run `cargo help bench` for more detailed information."
16)]
17pub struct Bench {
18    #[command(flatten)]
19    pub xwin: XWinOptions,
20
21    #[command(flatten)]
22    pub cargo: cargo_options::Bench,
23}
24
25impl Bench {
26    /// Create a new bench from manifest path
27    #[allow(clippy::field_reassign_with_default)]
28    pub fn new(manifest_path: Option<PathBuf>) -> Self {
29        let mut build = Self::default();
30        build.manifest_path = manifest_path;
31        build
32    }
33
34    /// Execute `cargo bench` command
35    pub fn execute(&self) -> Result<()> {
36        let mut run = self.build_command()?;
37
38        for target in &self.cargo.target {
39            if target.contains("msvc") {
40                if env::var_os("WINEDEBUG").is_none() {
41                    run.env("WINEDEBUG", "-all");
42                }
43                let env_target = target.to_uppercase().replace('-', "_");
44                let runner_env = format!("CARGO_TARGET_{}_RUNNER", env_target);
45                if env::var_os(&runner_env).is_none() {
46                    run.env(runner_env, "wine");
47                }
48            }
49        }
50
51        let mut child = run.spawn().context("Failed to run cargo run")?;
52        let status = child.wait().expect("Failed to wait on cargo run process");
53        if !status.success() {
54            process::exit(status.code().unwrap_or(1));
55        }
56        Ok(())
57    }
58
59    /// Generate cargo subcommand
60    pub fn build_command(&self) -> Result<Command> {
61        let mut build = self.cargo.command();
62        self.xwin.apply_command_env(
63            self.manifest_path.as_deref(),
64            &self.cargo.common,
65            &mut build,
66        )?;
67        Ok(build)
68    }
69}
70
71impl Deref for Bench {
72    type Target = cargo_options::Bench;
73
74    fn deref(&self) -> &Self::Target {
75        &self.cargo
76    }
77}
78
79impl DerefMut for Bench {
80    fn deref_mut(&mut self) -> &mut Self::Target {
81        &mut self.cargo
82    }
83}
84
85impl From<cargo_options::Bench> for Bench {
86    fn from(cargo: cargo_options::Bench) -> Self {
87        Self {
88            cargo,
89            ..Default::default()
90        }
91    }
92}