use crate::SourceCodeScanner;
impl<'src> SourceCodeScanner<'src> {
#[inline]
pub fn parse_indent_level(&self, chars_per_level: usize) -> usize {
let mut indent_char_count = 0usize;
while let Some(char) = self.peek() {
if char.is_whitespace() {
unsafe {
indent_char_count = indent_char_count.unchecked_add(1);
}
self.skip();
} else {
break;
}
}
indent_char_count.div_euclid(chars_per_level)
}
#[inline]
pub fn skip_whitespace(&self) {
while let Some(char) = self.peek() {
if char.is_whitespace() {
self.skip();
} else {
break;
}
}
}
#[inline]
pub fn skip_line(&self) {
while let Some(next) = self.next() {
if next == '\n' {
return;
}
}
}
}
#[cfg(test)]
mod tests {
use crate::{span::Span, SourceCodeScanner};
#[test]
fn get_indent_level() {
let code = SourceCodeScanner::new(
"
a
b
c
d
e
f
g
h
i
j
",
);
let next_line = |num| {
code.skip_until('\n');
code.skip();
assert_eq!(code.parse_indent_level(4), num);
};
next_line(3);
next_line(4);
next_line(4);
next_line(5);
next_line(3);
next_line(3);
next_line(4);
next_line(4);
next_line(4);
next_line(3);
}
#[test]
fn skip_whitespace() {
let code = SourceCodeScanner::new("a b \n c");
unsafe {
code.skip_whitespace();
assert_eq!(code.next_span(), Some(Span::new(0, 1).wrap('a')));
code.skip_whitespace();
assert_eq!(code.next_span(), Some(Span::new(8, 1).wrap('b')));
code.skip_whitespace();
assert_eq!(code.next_span(), Some(Span::new(14, 1).wrap('c')));
assert!(!code.has_next());
code.skip_whitespace();
assert!(!code.has_next());
}
}
#[test]
fn skip_line() {
let code = SourceCodeScanner::new("a whatever \nb \nc \r\r\nd etc");
assert!(code.peek_is('a'));
code.skip_line();
assert!(code.peek_is('b'));
code.skip_line();
assert!(code.peek_is('c'));
code.skip_line();
assert!(code.peek_is('d'));
code.skip_line();
assert!(!code.has_next());
}
}