general_parser/
lexer.rs

1pub struct Lexer<'a> {
2	on: &'a str,
3	idx: usize,
4}
5
6impl<'a> Lexer<'a> {
7	pub fn new(on: &'a str) -> Self {
8		Self { on, idx: 0 }
9	}
10
11	pub(crate) fn current(&self) -> &'a str {
12		&self.on[self.idx..]
13	}
14
15	pub(crate) fn finished(&self) -> bool {
16		self.current().is_empty()
17	}
18
19	pub(crate) fn skip(&mut self) {
20		for (idx, chr) in self.current().char_indices() {
21			if !chr.is_whitespace() {
22				self.advance(idx);
23				break;
24			}
25		}
26	}
27
28	// TODO some of these temp
29	pub(crate) fn parse_identifier(&mut self) -> &'a str {
30		self.skip();
31		let current = self.current();
32		if let Some(rest) = current.strip_prefix('"') {
33			let next = rest.find('"').unwrap();
34			self.advance(next + 2);
35			&current[..(next + 2)]
36		} else {
37			for (idx, chr) in current.char_indices() {
38				if !(chr.is_alphanumeric() || matches!(chr, '.')) {
39					self.advance(idx);
40					return &current[..idx];
41				}
42			}
43			self.advance(current.len());
44			assert!(!current.is_empty(), "empty identifier");
45			current
46		}
47	}
48
49	pub(crate) fn starts_with(&mut self, slice: &str) -> bool {
50		self.skip();
51		let current = self.current();
52		let matches = current.starts_with(slice);
53		let is_not_actually_operator = matches
54			&& slice.chars().all(char::is_alphanumeric)
55			&& current[slice.len()..].chars().next().is_some_and(char::is_alphanumeric);
56
57		if is_not_actually_operator { false } else { matches }
58	}
59
60	pub(crate) fn starts_with_value(&mut self) -> bool {
61		self.skip();
62		let current = self.current();
63		current.starts_with(|chr: char| chr.is_alphanumeric() || matches!(chr, '"' | '(' | '['))
64	}
65
66	pub(crate) fn advance(&mut self, idx: usize) {
67		self.idx += idx;
68	}
69}