fjord/
lexer.rs

1mod syntax_kind;
2pub(crate) use syntax_kind::SyntaxKind;
3
4use logos::Logos;
5use smol_str::SmolStr;
6use std::{convert::TryFrom, ops::Range};
7use text_size::{TextRange, TextSize};
8
9#[derive(Debug)]
10pub(crate) struct Lexeme {
11    pub(crate) kind: SyntaxKind,
12    pub(crate) text: SmolStr,
13    pub(crate) range: TextRange,
14}
15
16pub(crate) struct Lexer<'a> {
17    inner: logos::Lexer<'a, SyntaxKind>,
18}
19
20impl<'a> Lexer<'a> {
21    pub(crate) fn new(input: &'a str) -> Self {
22        Self {
23            inner: SyntaxKind::lexer(input),
24        }
25    }
26}
27
28impl Iterator for Lexer<'_> {
29    type Item = Lexeme;
30
31    fn next(&mut self) -> Option<Self::Item> {
32        let kind = self.inner.next()?;
33        let text = self.inner.slice().into();
34
35        let Range { start, end } = self.inner.span();
36        let start = TextSize::try_from(start).unwrap();
37        let end = TextSize::try_from(end).unwrap();
38        let range = TextRange::new(start, end);
39
40        Some(Lexeme { kind, text, range })
41    }
42}