/
mod.rs
197 lines (177 loc) · 6.27 KB
/
mod.rs
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
use std::{io::Write, process::Command};
use schemars::JsonSchema;
use tempfile::NamedTempFile;
use crate::{config::MdsfConfig, languages::Language, DEBUG};
pub mod autopep8;
pub mod beautysh;
pub mod biome;
pub mod black;
pub mod blade_formatter;
pub mod blue;
pub mod clang_format;
pub mod cljstyle;
pub mod crystal_format;
pub mod dart_format;
pub mod deno_fmt;
pub mod efmt;
pub mod elm_format;
pub mod erlfmt;
pub mod fantomas;
pub mod fourmolu;
pub mod gleam_format;
pub mod gofmt;
pub mod gofumpt;
pub mod goimports;
pub mod google_java_format;
pub mod hindent;
pub mod isort;
pub mod just_fmt;
pub mod ktfmt;
pub mod ktlint;
pub mod luaformatter;
pub mod mix_format;
pub mod nimpretty;
pub mod npm_groovy_lint;
pub mod ocamlformat;
pub mod ormolu;
pub mod perltidy;
pub mod prettier;
pub mod purs_tidy;
pub mod rescript_format;
pub mod roc_format;
pub mod rubocop;
pub mod rubyfmt;
pub mod ruff;
pub mod rufo;
pub mod rustfmt;
pub mod scalafmt;
pub mod shfmt;
pub mod sql_formatter;
pub mod sqlfluff;
pub mod standardrb;
pub mod stylua;
pub mod swiftformat;
pub mod taplo;
pub mod usort;
pub mod xmllint;
pub mod yamlfmt;
pub mod yapf;
pub mod zigfmt;
#[inline]
pub fn setup_snippet(code: &str, file_ext: &str) -> std::io::Result<NamedTempFile> {
let mut f = tempfile::Builder::new()
.rand_bytes(12)
.suffix(file_ext)
.prefix(
// ktlint wants PascalCase file names
if file_ext == Language::Kotlin.to_file_ext() {
"MdsfFile"
} else {
"mdsf"
},
)
.tempfile()?;
f.write_all(code.as_bytes())?;
f.flush()?;
Ok(f)
}
#[inline]
pub fn read_snippet(file_path: &std::path::Path) -> std::io::Result<String> {
std::fs::read_to_string(file_path)
}
#[inline]
fn handle_post_execution(
result: std::io::Result<bool>,
snippet_path: &std::path::Path,
) -> std::io::Result<(bool, Option<String>)> {
if let Err(err) = result {
if err.kind() == std::io::ErrorKind::NotFound {
return Ok((true, None));
}
return Err(err);
}
if matches!(result, Ok(true)) {
return read_snippet(snippet_path).map(|code| (false, Some(code)));
}
Ok((false, None))
}
fn spawn_command(cmd: &mut Command) -> std::io::Result<bool> {
if !DEBUG.load(core::sync::atomic::Ordering::Relaxed) {
cmd.stdout(std::process::Stdio::null());
cmd.stderr(std::process::Stdio::null());
}
Ok(cmd.spawn()?.wait()?.success())
}
#[inline]
pub fn execute_command(
cmd: &mut Command,
snippet_path: &std::path::Path,
) -> std::io::Result<(bool, Option<String>)> {
handle_post_execution(spawn_command(cmd), snippet_path)
}
#[inline]
pub fn format_snippet(config: &MdsfConfig, language: &Language, code: &str) -> String {
if let Ok(snippet) = setup_snippet(code, language.to_file_ext()) {
let snippet_path = snippet.path();
if let Ok(Some(formatted_code)) = match language {
Language::Blade => config.blade.format(snippet_path),
Language::C => config.c.format(snippet_path),
Language::Clojure => config.clojure.format(snippet_path),
Language::CSharp => config.csharp.format(snippet_path),
Language::Cpp => config.cpp.format(snippet_path),
Language::Crystal => config.crystal.format(snippet_path),
Language::Css => config.css.format(snippet_path),
Language::Dart => config.dart.format(snippet_path),
Language::Elixir => config.elixir.format(snippet_path),
Language::Elm => config.elm.format(snippet_path),
Language::Erlang => config.erlang.format(snippet_path),
Language::FSharp => config.fsharp.format(snippet_path),
Language::Gleam => config.gleam.format(snippet_path),
Language::Go => config.go.format(snippet_path),
Language::GraphQL => config.graphql.format(snippet_path),
Language::Groovy => config.groovy.format(snippet_path),
Language::Haskell => config.haskell.format(snippet_path),
Language::Html => config.html.format(snippet_path),
Language::Java => config.java.format(snippet_path),
Language::JavaScript => config.javascript.format(snippet_path),
Language::Json => config.json.format(snippet_path),
Language::Just => config.just.format(snippet_path),
Language::Kotlin => config.kotlin.format(snippet_path),
Language::Lua => config.lua.format(snippet_path),
Language::Markdown => config.markdown.format(snippet_path),
Language::Nim => config.nim.format(snippet_path),
Language::OCaml => config.ocaml.format(snippet_path),
Language::ObjectiveC => config.objective_c.format(snippet_path),
Language::Perl => config.perl.format(snippet_path),
Language::Protobuf => config.protobuf.format(snippet_path),
Language::Python => config.python.format(snippet_path),
Language::PureScript => config.purescript.format(snippet_path),
Language::ReScript => config.rescript.format(snippet_path),
Language::Roc => config.roc.format(snippet_path),
Language::Ruby => config.ruby.format(snippet_path),
Language::Rust => config.rust.format(snippet_path),
Language::Scala => config.scala.format(snippet_path),
Language::Shell => config.shell.format(snippet_path),
Language::Sql => config.sql.format(snippet_path),
Language::Swift => config.swift.format(snippet_path),
Language::Toml => config.toml.format(snippet_path),
Language::TypeScript => config.typescript.format(snippet_path),
Language::Vue => config.vue.format(snippet_path),
Language::Xml => config.xml.format(snippet_path),
Language::Yaml => config.yaml.format(snippet_path),
Language::Zig => config.zig.format(snippet_path),
} {
let mut f = formatted_code.trim().to_owned();
f.push('\n');
return f;
}
}
code.to_owned()
}
#[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)]
#[cfg_attr(test, derive(PartialEq, Eq))]
#[serde(untagged)]
pub enum MdsfFormatter<T> {
Single(T),
Multiple(Vec<MdsfFormatter<T>>),
}