cargo_zigbuild/
run.rs

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