pyro_artifacts/
command.rs1use std::path::Path;
4use thiserror::Error;
5
6use tokio::process::Command;
7
8#[derive(Error, Debug)]
9pub enum CommandError {
10 #[error("IO error: {0}")]
11 Io(#[from] std::io::Error),
12 #[error(
13 "Cargo command failed with status {status}. Args: {args:?}\nStdout: {stdout}\nStderr: {stderr}"
14 )]
15 Cargo {
16 status: std::process::ExitStatus,
17 args: Vec<String>,
18 stdout: String,
19 stderr: String,
20 },
21}
22
23pub async fn run_command(
25 root: &Path,
26 tool_args: &[&str],
27 capture: bool,
28) -> Result<String, CommandError> {
29 let mut cmd = Command::new("cargo");
30 cmd.args(tool_args).current_dir(&root);
31
32 if capture {
33 let output = cmd.output().await?;
34
35 if !output.status.success() {
36 return Err(CommandError::Cargo {
37 status: output.status,
38 args: tool_args.iter().map(|s| s.to_string()).collect(),
39 stdout: String::from_utf8_lossy(&output.stdout).to_string(),
40 stderr: String::from_utf8_lossy(&output.stderr).to_string(),
41 });
42 }
43 Ok(String::from_utf8_lossy(&output.stdout).to_string())
44 } else {
45 let status = cmd.status().await?;
46
47 if !status.success() {
48 return Err(CommandError::Cargo {
49 status,
50 args: tool_args.iter().map(|s| s.to_string()).collect(),
51 stdout: String::from("Not captured"),
52 stderr: String::from("Not captured"),
53 });
54 }
55 Ok(String::new())
56 }
57}
58
59pub fn format_syn_error(source: &str, err: syn::Error) -> String {
61 let span = err.span();
62 let start = span.start();
63 let msg = err.to_string();
64
65 let lines: Vec<&str> = source.lines().collect();
66 let line_num = start.line;
67 let col = start.column;
68
69 let mut output = String::new();
70 output.push_str(&format!("error: {}\n", msg));
71 output.push_str(&format!(" --> src/lib.rs:{}:{}\n", line_num, col + 1));
72 output.push_str(" |\n");
73
74 let start_line = line_num.saturating_sub(2);
76 let end_line = (line_num + 1).min(lines.len());
77
78 for i in start_line..end_line {
79 let line_content = lines.get(i).unwrap_or(&"");
80 let display_num = i + 1;
81
82 if display_num == line_num {
83 output.push_str(&format!("{:3} | {}\n", display_num, line_content));
84 output.push_str(&format!(" | {}^\n", " ".repeat(col)));
86 } else {
87 output.push_str(&format!("{:3} | {}\n", display_num, line_content));
88 }
89 }
90 output.push_str(" |\n");
91
92 output
93}