1use crate::prelude::*;
2use crate::Example;
5
6#[cfg(feature = "equivalent")]
8pub fn run_example(example: &Example, extra_args: &[String]) -> Result<(), Box<dyn Error>> {
9 let mut cmd = Command::new("cargo");
11 cmd.args(["run", "--example", &example.name]);
12 if !extra_args.is_empty() {
13 cmd.arg("--").args(extra_args);
14 }
15 use std::process::Stdio;
17 cmd.stdin(Stdio::inherit())
18 .stdout(Stdio::inherit())
19 .stderr(Stdio::inherit());
20
21 let status = cmd.status()?;
22 std::process::exit(status.code().unwrap_or(1));
23}
24
25#[cfg(not(feature = "equivalent"))]
27pub fn run_example(target: &Example, extra_args: &[String]) -> Result<(), Box<dyn Error>> {
28 let current_bin = env!("CARGO_PKG_NAME");
30
31 if target.kind == crate::TargetKind::Binary && target.name == current_bin {
34 return Err(format!(
35 "Skipping automatic run: {} is the same as the running binary",
36 target.name
37 )
38 .into());
39 }
40
41 let mut cmd = Command::new("cargo");
42
43 match target.kind {
44 crate::TargetKind::Example => {
46 if target.extended {
47 println!(
48 "Running extended example in folder: examples/{}",
49 target.name
50 );
51 cmd.arg("run")
52 .current_dir(format!("examples/{}", target.name));
53 } else {
54 cmd.args(["run", "--release", "--example", &target.name]);
55 }
56 }
57 crate::TargetKind::Binary => {
59 println!("Running binary: {}", target.name);
60 cmd.args(["run", "--release", "--bin", &target.name]);
61 } }
66
67 if !extra_args.is_empty() {
68 cmd.arg("--").args(extra_args);
69 }
70
71 let full_command = format!(
72 "cargo {}",
73 cmd.get_args()
74 .map(|arg| arg.to_string_lossy())
75 .collect::<Vec<_>>()
76 .join(" ")
77 );
78 println!("Running: {}", full_command);
79
80 let child = cmd.spawn()?;
81 use std::sync::{Arc, Mutex};
82 let child_arc = Arc::new(Mutex::new(child));
83 let child_for_handler = Arc::clone(&child_arc);
84
85 ctrlc::set_handler(move || {
86 eprintln!("Ctrl+C pressed, terminating process...");
87 let mut child = child_for_handler.lock().unwrap();
88 let _ = child.kill();
89 })?;
90
91 let status = child_arc.lock().unwrap().wait()?;
92 println!("Process exited with status: {:?}", status.code());
93 Ok(())
94}
95
96pub fn spawn_cargo_process(args: &[&str]) -> Result<Child, Box<dyn Error>> {
99 #[cfg(windows)]
100 {
101 use std::os::windows::process::CommandExt;
102 const CREATE_NEW_PROCESS_GROUP: u32 = 0x00000200;
103 let child = Command::new("cargo")
104 .args(args)
105 .creation_flags(CREATE_NEW_PROCESS_GROUP)
106 .spawn()?;
107 Ok(child)
108 }
109 #[cfg(not(windows))]
110 {
111 let child = Command::new("cargo").args(args).spawn()?;
112 Ok(child)
113 }
114}