use std::ops::Range;
use logos::Logos;
#[derive(Debug)]
pub struct Token<'a> {
pub kind: TokenKind,
pub lexeme: &'a str,
pub span: Range<usize>,
}
#[derive(Logos, Debug, PartialEq)]
pub enum TokenKind {
#[regex("[a-zA-Z]+")]
Alpha,
#[regex("[0-9]+")]
Number,
#[token("-")]
Dash,
#[token(".")]
Delim,
#[token("*")]
Star,
#[error]
Error,
}
pub struct Lexer<'a> {
lexer: logos::Lexer<'a, TokenKind>,
}
impl<'a> Lexer<'a> {
pub fn new(input: &'a str) -> Self {
Self {
lexer: TokenKind::lexer(input),
}
}
}
impl<'a> Iterator for Lexer<'a> {
type Item = Token<'a>;
fn next(&mut self) -> Option<Self::Item> {
let kind = self.lexer.next()?;
let lexeme = self.lexer.slice();
let span = self.lexer.span();
Some(Token {
kind: kind.into(),
lexeme,
span,
})
}
}