Skip to content

Commit 05265d7

Browse files
authored
chore: replace CharIterator struct with IteratorCharExt trait (#315)
1 parent 3457487 commit 05265d7

File tree

2 files changed

+56
-90
lines changed

2 files changed

+56
-90
lines changed

src/utils/char_iterator.rs

Lines changed: 29 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,43 @@
1-
// todo: This is not good at all and very specific to it's use at the moment.
2-
// Over time this should be improved.
3-
4-
pub struct CharIterator<'a> {
5-
chars: std::str::Chars<'a>,
6-
next_char: Option<char>,
7-
}
8-
9-
impl<'a> CharIterator<'a> {
10-
pub fn new(chars: std::str::Chars<'a>) -> CharIterator<'a> {
11-
CharIterator { chars, next_char: None }
1+
use std::{iter::Peekable, str::Chars};
2+
3+
pub trait IteratorCharExt: Iterator<Item = char> {
4+
fn peek(&mut self) -> Option<&char>;
5+
6+
fn check_text(&mut self, text: &str) -> bool {
7+
let mut text_iter = text.chars();
8+
while let Some(text_ch) = text_iter.next() {
9+
match self.peek() {
10+
Some(ch) if *ch == text_ch => self.next(),
11+
_ => return false,
12+
};
13+
}
14+
true
1215
}
1316

14-
pub fn skip_whitespace(&mut self) {
15-
while let Some(c) = self.peek_next() {
16-
if !c.is_whitespace() {
17-
return;
18-
} else {
19-
self.move_next();
20-
}
21-
}
17+
fn skip_whitespace(&mut self) {
18+
self.skip_while(char::is_whitespace);
2219
}
2320

24-
pub fn skip_spaces(&mut self) {
25-
while let Some(c) = self.peek_next() {
26-
if c != ' ' {
27-
return;
28-
} else {
29-
self.move_next();
30-
}
31-
}
21+
fn skip_spaces(&mut self) {
22+
self.skip_while(|c| c == ' ');
3223
}
3324

34-
pub fn skip_all_until_new_line(&mut self) {
35-
while let Some(c) = self.move_next() {
36-
if c == '\r' {
37-
if self.peek_next() == Some('\n') {
38-
self.move_next();
39-
}
40-
return;
41-
} else if c == '\n' {
42-
return;
43-
}
44-
}
25+
fn skip_all_until_new_line(&mut self) {
26+
self.skip_while(|c| c != '\n');
4527
}
4628

47-
pub fn check_text(&mut self, text: &str) -> bool {
48-
for c in text.chars() {
49-
if let Some(comparison_char) = self.peek_next() {
50-
if comparison_char != c {
51-
return false;
52-
} else {
53-
self.move_next();
54-
}
55-
} else {
56-
return false;
29+
fn skip_while<P: Fn(char) -> bool>(&mut self, predicate: P) {
30+
while let Some(ch) = self.peek() {
31+
if !predicate(*ch) {
32+
break;
5733
}
34+
self.next();
5835
}
59-
60-
true
61-
}
62-
63-
pub fn move_next(&mut self) -> Option<char> {
64-
self.ensure_next_char();
65-
let current_char = self.next_char;
66-
self.next_char = self.chars.next();
67-
current_char
68-
}
69-
70-
pub fn peek_next(&mut self) -> Option<char> {
71-
self.ensure_next_char();
72-
self.next_char
7336
}
37+
}
7438

75-
fn ensure_next_char(&mut self) {
76-
if self.next_char.is_none() {
77-
self.next_char = self.chars.next();
78-
}
39+
impl<'a> IteratorCharExt for Peekable<Chars<'a>> {
40+
fn peek(&mut self) -> Option<&char> {
41+
self.peek()
7942
}
8043
}

src/utils/file_text_has_ignore_comment.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,62 @@
1+
use crate::utils::char_iterator::IteratorCharExt;
2+
use std::{
3+
iter::{Iterator, Peekable},
4+
str::Chars,
5+
};
6+
17
pub fn file_text_has_ignore_comment(file_text: &str, ignore_text: &str) -> bool {
2-
let mut iterator = super::CharIterator::new(file_text.chars());
8+
let mut chars = file_text.chars().peekable();
39

410
// skip over the shebang
511
if file_text.starts_with("#!") {
6-
iterator.move_next();
7-
iterator.move_next();
8-
iterator.skip_all_until_new_line();
12+
chars.next();
13+
chars.next();
14+
chars.skip_all_until_new_line();
915
}
1016

1117
// now handle the comments
12-
while iterator.peek_next().is_some() {
13-
iterator.skip_whitespace();
14-
if iterator.move_next() != Some('/') {
18+
while chars.peek().is_some() {
19+
chars.skip_whitespace();
20+
if chars.next() != Some('/') {
1521
return false;
1622
}
17-
match iterator.move_next() {
23+
match chars.next() {
1824
Some('/') => {
19-
if check_single_line_comment(&mut iterator, ignore_text) {
25+
if check_single_line_comment(&mut chars, ignore_text) {
2026
return true;
2127
}
2228
}
2329
Some('*') => {
24-
if check_multi_line_comment(&mut iterator, ignore_text) {
30+
if check_multi_line_comment(&mut chars, ignore_text) {
2531
return true;
2632
}
2733
}
2834
_ => return false,
2935
}
3036
}
31-
3237
return false;
3338

34-
fn check_single_line_comment(iterator: &mut super::CharIterator, ignore_text: &str) -> bool {
35-
iterator.skip_spaces(); // only spaces, not whitespace
36-
if iterator.check_text(ignore_text) {
39+
fn check_single_line_comment(chars: &mut Peekable<Chars>, ignore_text: &str) -> bool {
40+
chars.skip_spaces(); // only spaces, not whitespace
41+
if chars.check_text(ignore_text) {
3742
return true;
3843
}
39-
40-
iterator.skip_all_until_new_line();
41-
44+
chars.skip_all_until_new_line();
4245
false
4346
}
4447

45-
fn check_multi_line_comment(iterator: &mut super::CharIterator, ignore_text: &str) -> bool {
46-
iterator.skip_whitespace();
47-
if iterator.check_text(ignore_text) {
48+
fn check_multi_line_comment(chars: &mut Peekable<Chars>, ignore_text: &str) -> bool {
49+
chars.skip_whitespace();
50+
if chars.check_text(ignore_text) {
4851
return true;
4952
}
50-
while let Some(c) = iterator.move_next() {
51-
if c == '*' && iterator.peek_next() == Some('/') {
52-
iterator.move_next();
53+
54+
while let Some(c) = chars.next() {
55+
if c == '*' && chars.peek() == Some(&'/') {
56+
chars.next();
5357
return false;
5458
}
5559
}
56-
5760
false
5861
}
5962
}

0 commit comments

Comments
 (0)