1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use crate::{
error::{Error, Result},
gen::SourceFormatter,
};
#[derive(Default)]
pub struct NullFormatter {}
impl SourceFormatter for NullFormatter {}
pub struct RustSourceFormatter {
program: String,
edition: String,
extra: Vec<String>,
}
impl Default for RustSourceFormatter {
fn default() -> Self {
RustSourceFormatter {
program: "rustfmt".to_string(),
edition: "2021".to_string(),
extra: Vec::new(),
}
}
}
impl SourceFormatter for RustSourceFormatter {
fn run(&self, source_files: &[&str]) -> Result<()> {
if !matches!(self.edition.as_str(), "2015" | "2018" | "2021") {
return Err(Error::Formatter(format!(
"invalid edition: {}",
self.edition
)));
}
let mut args = vec![
"--edition",
&self.edition,
"--config",
"format_generated_files=true",
];
args.extend(self.extra.iter().map(|s| s.as_str()));
args.extend(source_files.iter());
run_command(&self.program, &args)?;
Ok(())
}
}
pub struct GoSourceFormatter {
program: String,
args: Vec<String>,
}
impl Default for GoSourceFormatter {
fn default() -> Self {
GoSourceFormatter {
program: "go".into(),
args: vec!["fmt".into()],
}
}
}
impl SourceFormatter for GoSourceFormatter {
fn run(&self, source_files: &[&str]) -> Result<()> {
for f in source_files {
let mut args = self.args.clone();
let path = std::fs::canonicalize(f)?;
args.push(path.to_string_lossy().to_string());
let str_args: Vec<&str> = args.iter().map(|s| s.as_str()).collect();
if let Err(e) = run_command(&self.program, &str_args) {
eprintln!("Warning: formatting '{}': {}", path.display(), e);
}
}
Ok(())
}
}
pub(crate) fn run_command(program: &str, args: &[&str]) -> Result<()> {
let mut child = std::process::Command::new(program)
.args(args.iter())
.spawn()
.map_err(|e| Error::Formatter(format!("failed to start: {}", e)))?;
let code = child
.wait()
.map_err(|e| Error::Formatter(format!("failed waiting for formatter: {}", e)))?;
if !code.success() {
return Err(Error::Formatter(code.to_string()));
}
Ok(())
}