aboutsummaryrefslogtreecommitdiff
path: root/bin/src/fix.rs
diff options
context:
space:
mode:
Diffstat (limited to 'bin/src/fix.rs')
-rw-r--r--bin/src/fix.rs60
1 files changed, 26 insertions, 34 deletions
diff --git a/bin/src/fix.rs b/bin/src/fix.rs
index 478dbd9..d9087fe 100644
--- a/bin/src/fix.rs
+++ b/bin/src/fix.rs
@@ -65,48 +65,40 @@ pub struct Fixed {
65 65
66impl<'a> FixResult<'a> { 66impl<'a> FixResult<'a> {
67 fn empty(src: Source<'a>) -> Self { 67 fn empty(src: Source<'a>) -> Self {
68 Self { src, fixed: vec![] } 68 Self { src, fixed: Vec::new() }
69 } 69 }
70} 70}
71 71
72fn next(mut src: Source) -> Result<FixResult, RnixParseErr> { 72impl<'a> Iterator for FixResult<'a> {
73 let all_reports = collect_fixes(&src)?; 73 type Item = FixResult<'a>;
74 74 fn next(&mut self) -> Option<Self::Item> {
75 if all_reports.is_empty() { 75 let all_reports = collect_fixes(&self.src).ok()?;
76 return Ok(FixResult::empty(src)); 76 if all_reports.is_empty() {
77 } 77 return None;
78 }
78 79
79 let reordered = reorder(all_reports); 80 let reordered = reorder(all_reports);
81 let fixed = reordered
82 .iter()
83 .map(|r| Fixed {
84 at: r.range(),
85 code: r.code,
86 })
87 .collect::<Vec<_>>();
88 for report in reordered {
89 report.apply(self.src.to_mut());
90 }
80 91
81 let fixed = reordered 92 Some(FixResult {
82 .iter() 93 src: self.src.clone(),
83 .map(|r| Fixed { 94 fixed
84 at: r.range(),
85 code: r.code,
86 }) 95 })
87 .collect::<Vec<_>>();
88 for report in reordered {
89 report.apply(src.to_mut());
90 } 96 }
91
92 Ok(FixResult {
93 src,
94 fixed
95 })
96} 97}
97 98
98pub fn fix(src: &str) -> Result<FixResult, RnixParseErr> { 99pub fn fix(src: &str) -> Option<FixResult> {
99 let src = Cow::from(src); 100 let src = Cow::from(src);
100 let _ = rnix::parse(&src).as_result()?; 101 let _ = rnix::parse(&src).as_result().ok()?;
101 let mut initial = FixResult::empty(src); 102 let initial = FixResult::empty(src);
102 103 initial.into_iter().last()
103 while let Ok(next_result) = next(initial.src) {
104 if next_result.fixed.is_empty() {
105 return Ok(next_result);
106 } else {
107 initial = FixResult::empty(next_result.src);
108 }
109 }
110
111 unreachable!("a fix caused a syntax error, please report a bug");
112} 104}