pub(crate) struct Cursor {
chars: Vec<(u32, char)>,
index: usize,
len: u32,
}
impl Cursor {
pub(crate) fn new(text: &str) -> Cursor {
let chars = text
.char_indices()
.map(|(offset, c)| (u32::try_from(offset).unwrap_or(u32::MAX), c))
.collect();
Cursor {
chars,
index: 0,
len: u32::try_from(text.len()).unwrap_or(u32::MAX),
}
}
pub(crate) fn peek(&self, n: usize) -> Option<char> {
self.chars.get(self.index + n).map(|&(_, c)| c)
}
pub(crate) fn prev(&self) -> Option<char> {
let index = self.index.checked_sub(1)?;
self.chars.get(index).map(|&(_, c)| c)
}
pub(crate) fn offset(&self) -> u32 {
self.chars
.get(self.index)
.map(|&(offset, _)| offset)
.unwrap_or(self.len)
}
pub(crate) fn bump(&mut self) -> Option<char> {
let c = self.peek(0)?;
self.index += 1;
Some(c)
}
pub(crate) fn eat(&mut self, expected: char) -> bool {
if self.peek(0) == Some(expected) {
self.index += 1;
true
} else {
false
}
}
}