#[derive(Debug)]
pub struct TokenReader {
source: std::rc::Rc<str>,
pub cursor: usize,
}
impl TokenReader {
pub fn new(source: std::rc::Rc<str>) -> Self {
Self {
source,
cursor: 0,
}
}
pub fn peek_char(&mut self) -> Option<char> {
self.source.get(self.cursor..)?.chars().next()
}
pub fn next_char(&mut self) -> Option<char> {
let peek = self.peek_char();
if let Some(peek) = peek {
self.cursor += peek.len_utf8();
}
peek
}
pub fn next_char_if(&mut self, pred: impl FnOnce(char) -> bool) -> Option<char> {
let peek = self.peek_char();
if let Some(peek) = peek {
if pred(peek) {
self.cursor += peek.len_utf8();
return Some(peek);
}
}
None
}
pub fn next_token(&mut self, pred: impl Fn(char) -> bool, prefix: impl Into<String>) -> String {
let mut buffer = prefix.into();
while let Some(char) = self.next_char_if(&pred) {
buffer.push(char);
}
buffer
}
}