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
|
use std::borrow::Cow;
use rnix::TextRange;
mod all;
use all::all;
mod single;
use single::single;
type Source<'a> = Cow<'a, str>;
#[derive(Debug)]
pub struct FixResult<'a> {
pub src: Source<'a>,
pub fixed: Vec<Fixed>,
}
#[derive(Debug, Clone)]
pub struct Fixed {
pub at: TextRange,
pub code: u32,
}
impl<'a> FixResult<'a> {
fn empty(src: Source<'a>) -> Self {
Self {
src,
fixed: Vec::new(),
}
}
}
pub mod main {
use std::borrow::Cow;
use crate::{
config::{Fix as FixConfig, FixOut, Single as SingleConfig},
err::{FixErr, StatixErr},
};
use similar::TextDiff;
pub fn all(fix_config: FixConfig) -> Result<(), StatixErr> {
let vfs = fix_config.vfs()?;
for entry in vfs.iter() {
match (fix_config.out(), super::all(entry.contents)) {
(FixOut::Diff, fix_result) => {
let src = fix_result
.map(|r| r.src)
.unwrap_or(Cow::Borrowed(entry.contents));
let text_diff = TextDiff::from_lines(entry.contents, &src);
let old_file = format!("{}", entry.file_path.display());
let new_file = format!("{} [fixed]", entry.file_path.display());
println!(
"{}",
text_diff
.unified_diff()
.context_radius(4)
.header(&old_file, &new_file)
);
}
(FixOut::Stream, fix_result) => {
let src = fix_result
.map(|r| r.src)
.unwrap_or(Cow::Borrowed(entry.contents));
println!("{}", &src)
}
(FixOut::Write, Some(fix_result)) => {
let path = entry.file_path;
std::fs::write(path, &*fix_result.src).map_err(FixErr::InvalidPath)?;
}
_ => (),
};
}
Ok(())
}
pub fn single(single_config: SingleConfig) -> Result<(), StatixErr> {
let vfs = single_config.vfs()?;
let entry = vfs.iter().next().unwrap();
let path = entry.file_path.display().to_string();
let original_src = entry.contents;
let (line, col) = single_config.position;
match (single_config.out(), super::single(line, col, original_src)) {
(FixOut::Diff, single_result) => {
let fixed_src = single_result
.map(|r| r.src)
.unwrap_or(Cow::Borrowed(original_src));
let text_diff = TextDiff::from_lines(original_src, &fixed_src);
let old_file = &path;
let new_file = format!("{} [fixed]", &path);
println!(
"{}",
text_diff
.unified_diff()
.context_radius(4)
.header(&old_file, &new_file)
);
}
(FixOut::Stream, single_result) => {
let src = single_result
.map(|r| r.src)
.unwrap_or(Cow::Borrowed(original_src));
println!("{}", &src)
}
(FixOut::Write, Ok(single_result)) => {
let path = entry.file_path;
std::fs::write(path, &*single_result.src).map_err(FixErr::InvalidPath)?;
}
(_, Err(e)) => return Err(e.into()),
};
Ok(())
}
}
|