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}