saffron-data 0.1.1

Custom JSON parser for Saffron HTTP client
Documentation
use crate::tokenizer::{Span, Token, TokenKind};

#[derive(Default)]
pub struct TokenStream {
    tokens: Vec<Token>,
    position: usize,
}

impl TokenStream {
    pub fn new(tokens: Vec<Token>) -> Self {
        Self {
            tokens,
            position: 0,
        }
    }

    pub fn previous(&self) -> Token {
        if self.tokens.is_empty() {
            return Token::new(TokenKind::EndOfFile, "\0".into(), 0, 0, Span(0, 0));
        }

        if self.position == 0 {
            return self.tokens[0].clone();
        }

        let pos = if self.position > self.tokens.len() {
            self.tokens.len() - 1
        } else {
            self.position - 1
        };

        self.tokens[pos].clone()
    }

    pub fn current(&self) -> Token {
        if self.tokens.is_empty() {
            return Token::new(TokenKind::EndOfFile, "\0".into(), 0, 0, Span(0, 0));
        }

        if self.position >= self.tokens.len() {
            return self.tokens.last().unwrap().clone();
        }

        self.tokens[self.position].clone()
    }

    pub fn advance(&mut self) -> Token {
        self.position += 1;
        self.previous()
    }

    pub fn look_ahead(&self, k: usize) -> Token {
        if self.tokens.is_empty() {
            return Token::new(TokenKind::EndOfFile, "\0".into(), 0, 0, Span(0, 0));
        }

        if self.position + k >= self.tokens.len() {
            return self.tokens.last().unwrap().clone();
        }

        self.tokens[self.position + k].clone()
    }

    pub fn backtrack(&mut self) {
        self.position -= 1;
    }
}

impl From<TokenStream> for Vec<Token> {
    fn from(value: TokenStream) -> Self {
        value.tokens
    }
}