knave-expand 0.14.22

The reading, scoping and expansion stages of knave
Documentation
use super::syntax::Syntax;

pub struct Cursor<'a> {
    text: &'a str,
    position: usize,
}

impl<'a> Cursor<'a> {
    pub fn starting_at(text: &'a str, position: usize) -> Self {
        Self { text, position }
    }

    pub fn peek(&self) -> Option<char> {
        self.text[self.position..].chars().next()
    }

    pub fn advance(&mut self) -> Option<char> {
        let next = self.peek()?;
        self.position += next.len_utf8();
        Some(next)
    }

    pub fn advance_while(&mut self, continues: impl Fn(char) -> bool) -> &'a str {
        let start = self.position;
        while self.peek().is_some_and(&continues) {
            self.advance();
        }
        &self.text[start..self.position]
    }

    pub fn skip_whitespace(&mut self) {
        self.advance_while(char::is_whitespace);
    }

    pub fn advance_atom(&mut self) -> &'a str {
        self.advance_while(|character| !Syntax::ends_atom(character))
    }

    pub fn advance_to_line_end(&mut self) -> &'a str {
        self.advance_while(|character| character != Syntax::NEWLINE)
    }

    pub fn position(&self) -> usize {
        self.position
    }
}