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#[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 #[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 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 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}