diff options
Diffstat (limited to 'bin/src/fix/single.rs')
-rw-r--r-- | bin/src/fix/single.rs | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/bin/src/fix/single.rs b/bin/src/fix/single.rs index d430693..24b5c51 100644 --- a/bin/src/fix/single.rs +++ b/bin/src/fix/single.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::{borrow::Cow, convert::TryFrom}; | 1 | use std::{borrow::Cow, convert::TryFrom}; |
2 | 2 | ||
3 | use lib::{Report, LINTS}; | 3 | use lib::{Report, LINTS}; |
4 | use rnix::{TextRange, TextSize}; | 4 | use rnix::{TextSize, WalkEvent}; |
5 | 5 | ||
6 | use crate::err::SingleFixErr; | 6 | use crate::err::SingleFixErr; |
7 | use crate::fix::Source; | 7 | use crate::fix::Source; |
@@ -12,7 +12,7 @@ pub struct SingleFixResult<'δ> { | |||
12 | 12 | ||
13 | fn pos_to_byte(line: usize, col: usize, src: &str) -> Result<TextSize, SingleFixErr> { | 13 | fn pos_to_byte(line: usize, col: usize, src: &str) -> Result<TextSize, SingleFixErr> { |
14 | let mut byte: TextSize = TextSize::of(""); | 14 | let mut byte: TextSize = TextSize::of(""); |
15 | for (_, l) in src.lines().enumerate().take_while(|(i, _)| i <= &line) { | 15 | for (l, _) in src.split_inclusive('\n').zip(1..).take_while(|(_, i)| i < &line) { |
16 | byte += TextSize::of(l); | 16 | byte += TextSize::of(l); |
17 | } | 17 | } |
18 | byte += TextSize::try_from(col).map_err(|_| SingleFixErr::Conversion(col))?; | 18 | byte += TextSize::try_from(col).map_err(|_| SingleFixErr::Conversion(col))?; |
@@ -25,24 +25,31 @@ fn pos_to_byte(line: usize, col: usize, src: &str) -> Result<TextSize, SingleFix | |||
25 | } | 25 | } |
26 | 26 | ||
27 | fn find(offset: TextSize, src: &str) -> Result<Report, SingleFixErr> { | 27 | fn find(offset: TextSize, src: &str) -> Result<Report, SingleFixErr> { |
28 | let offset = offset - TextSize::from(1u32); | ||
28 | // we don't really need the source to form a completely parsed tree | 29 | // we don't really need the source to form a completely parsed tree |
29 | let parsed = rnix::parse(src); | 30 | let parsed = rnix::parse(src); |
30 | 31 | ||
31 | let elem_at = parsed | 32 | parsed |
32 | .node() | 33 | .node() |
33 | .child_or_token_at_range(TextRange::empty(offset)) | 34 | .preorder_with_tokens() |
34 | .ok_or(SingleFixErr::NoOp)?; | 35 | .filter_map(|event| match event { |
35 | 36 | WalkEvent::Enter(child) => { | |
36 | LINTS | 37 | if child.text_range().start() == offset { |
37 | .get(&elem_at.kind()) | 38 | LINTS.get(&child.kind()).map(|rules| { |
38 | .map(|rules| { | 39 | rules |
39 | rules | 40 | .iter() |
40 | .iter() | 41 | .filter_map(|rule| rule.validate(&child)) |
41 | .filter_map(|rule| rule.validate(&elem_at)) | 42 | .filter(|report| report.total_suggestion_range().is_some()) |
42 | .filter(|report| report.total_suggestion_range().is_some()) | 43 | .next() |
43 | .next() | 44 | }) |
45 | } else { | ||
46 | None | ||
47 | } | ||
48 | }, | ||
49 | _ => None | ||
44 | }) | 50 | }) |
45 | .flatten() | 51 | .flatten() |
52 | .next() | ||
46 | .ok_or(SingleFixErr::NoOp) | 53 | .ok_or(SingleFixErr::NoOp) |
47 | } | 54 | } |
48 | 55 | ||