1#![cfg_attr(docsrs, feature(doc_auto_cfg))]
88
89use core::fmt::Debug;
90
91use notification::{Notification, NotificationAcceptor, NotificationList};
92use token::Token;
93
94#[cfg(feature = "common")]
95pub mod common;
96pub mod notification;
97mod scanner;
98pub mod span;
99pub mod token;
100
101pub use scanner::SourceCodeScanner;
102
103#[derive(Debug)]
108pub struct LexerResult<TokenData, N = ()> {
109 notifications: NotificationList<N>,
111 tokens: Vec<Token<TokenData>>,
113}
114
115impl<T, N> NotificationAcceptor<N> for LexerResult<T, N> {
116 #[inline]
117 fn report(&mut self, notification: Notification<N>) {
118 self.notifications.push(notification);
119 }
120}
121
122impl<T, N> Default for LexerResult<T, N> {
123 fn default() -> Self {
124 Self {
125 notifications: NotificationList::new(),
126 tokens: vec![],
127 }
128 }
129}
130
131impl<T, N> LexerResult<T, N> {
132 #[must_use]
134 pub const fn new() -> Self {
135 Self {
136 notifications: NotificationList::new(),
137 tokens: vec![],
138 }
139 }
140
141 #[inline]
143 pub fn push_token(&mut self, token: Token<T>) {
144 self.tokens.push(token);
145 }
146
147 #[inline]
150 #[must_use]
151 pub fn finalize(self) -> FinalizedLexerResult<T, N> {
152 FinalizedLexerResult {
153 notifications: self.notifications,
154 tokens: self.tokens,
155 }
156 }
157}
158
159#[derive(Debug)]
163pub struct FinalizedLexerResult<TokenData, N = ()> {
164 notifications: NotificationList<N>,
166 tokens: Vec<Token<TokenData>>,
168}
169
170impl<T, N> FinalizedLexerResult<T, N> {
171 #[inline]
173 #[must_use]
174 pub const fn notifications(&self) -> &NotificationList<N> {
175 &self.notifications
176 }
177
178 #[inline]
181 #[must_use]
182 pub fn tokens(&self) -> Option<&Vec<Token<T>>> {
183 self.notifications.is_valid().then_some(&self.tokens)
184 }
185
186 #[inline]
191 #[must_use]
192 pub fn into_pair(self) -> (NotificationList<N>, Option<Vec<Token<T>>>) {
193 let valid = self.notifications.is_valid();
194
195 (self.notifications, valid.then_some(self.tokens))
196 }
197}
198
199#[cfg(test)]
200mod tests {
201 use crate::{span::Span, token::Token, LexerResult, SourceCodeScanner};
202
203 pub fn common() -> SourceCodeScanner<'static> {
204 SourceCodeScanner::new("Testing.")
205 }
206
207 #[test]
208 fn next() {
209 let code = common();
210
211 assert_eq!(code.next(), Some('T'));
212 assert_eq!(code.next(), Some('e'));
213 assert_eq!(code.next(), Some('s'));
214 assert_eq!(code.next(), Some('t'));
215 assert_eq!(code.next(), Some('i'));
216 assert_eq!(code.next(), Some('n'));
217 assert_eq!(code.next(), Some('g'));
218 assert_eq!(code.next(), Some('.'));
219 assert_eq!(code.next(), None);
220 }
221
222 #[test]
223 fn next_span() {
224 let code = common();
225
226 unsafe {
228 assert_eq!(code.next_span(), Some(Span::new(0, 1).wrap('T')));
229 assert_eq!(code.next_span(), Some(Span::new(1, 1).wrap('e')));
230 assert_eq!(code.next_span(), Some(Span::new(2, 1).wrap('s')));
231 assert_eq!(code.next_span(), Some(Span::new(3, 1).wrap('t')));
232 assert_eq!(code.next_span(), Some(Span::new(4, 1).wrap('i')));
233 assert_eq!(code.next_span(), Some(Span::new(5, 1).wrap('n')));
234 assert_eq!(code.next_span(), Some(Span::new(6, 1).wrap('g')));
235 assert_eq!(code.next_span(), Some(Span::new(7, 1).wrap('.')));
236 assert_eq!(code.next_span(), None);
237 }
238 }
239
240 #[test]
241 fn peek() {
242 let code = common();
243
244 assert_eq!(code.peek(), Some('T'));
245 assert_eq!(code.next(), Some('T'));
246 assert_eq!(code.next(), Some('e'));
247 assert_eq!(code.next(), Some('s'));
248 assert_eq!(code.next(), Some('t'));
249 assert_eq!(code.peek(), Some('i'));
250 assert_eq!(code.next(), Some('i'));
251 assert_eq!(code.next(), Some('n'));
252 assert_eq!(code.next(), Some('g'));
253 assert_eq!(code.peek(), Some('.'));
254 assert_eq!(code.next(), Some('.'));
255 assert_eq!(code.peek(), None);
256 assert_eq!(code.next(), None);
257 assert_eq!(code.peek(), None);
258 }
259
260 #[test]
261 fn has_next() {
262 let code = common();
263
264 assert_eq!(code.next(), Some('T'));
265 assert_eq!(code.next(), Some('e'));
266 assert!(code.has_next());
267 assert_eq!(code.next(), Some('s'));
268 assert_eq!(code.next(), Some('t'));
269 assert!(code.has_next());
270 assert_eq!(code.next(), Some('i'));
271 assert_eq!(code.next(), Some('n'));
272 assert_eq!(code.next(), Some('g'));
273 assert!(code.has_next());
274 assert_eq!(code.next(), Some('.'));
275 assert!(!code.has_next());
276 assert_eq!(code.next(), None);
277 assert!(!code.has_next());
278 }
279
280 #[test]
281 fn skip() {
282 let code = common();
283
284 assert_eq!(code.next(), Some('T'));
285 assert_eq!(code.next(), Some('e'));
286 code.skip();
287 assert_eq!(code.next(), Some('t'));
288 assert_eq!(code.next(), Some('i'));
289 code.skip();
290 assert_eq!(code.next(), Some('g'));
291 code.skip();
292 assert_eq!(code.next(), None);
293 }
294
295 #[test]
296 fn peek_is() {
297 let code = common();
298
299 assert_eq!(code.next(), Some('T'));
300 assert_eq!(code.next(), Some('e'));
301 assert!(code.peek_is('s'));
302 assert_eq!(code.next(), Some('s'));
303 assert_eq!(code.next(), Some('t'));
304 assert_eq!(code.next(), Some('i'));
305 assert!(code.peek_is('n'));
306 assert_eq!(code.next(), Some('n'));
307 assert!(code.peek_is_not('P'));
308 assert_eq!(code.next(), Some('g'));
309 assert!(code.peek_is('.'));
310 assert_eq!(code.next(), Some('.'));
311 assert!(code.peek_is_not('P'));
312 assert_eq!(code.next(), None);
313 assert!(code.peek_is_not('P'));
314 }
315
316 #[test]
317 fn peek_is_map() {
318 let code = common();
319
320 assert!(code.peek_is_map(|x| x.is_uppercase()));
321 assert_eq!(code.next(), Some('T'));
322 assert_eq!(code.next(), Some('e'));
323 assert!(!code.peek_is_map(|x| x.is_uppercase()));
324 assert_eq!(code.next(), Some('s'));
325 assert_eq!(code.next(), Some('t'));
326 assert_eq!(code.next(), Some('i'));
327 assert!(code.peek_is_map(|x| x.is_lowercase()));
328 assert_eq!(code.next(), Some('n'));
329 assert_eq!(code.next(), Some('g'));
330 assert!(!code.peek_is_map(|x| x.is_lowercase()));
331 assert_eq!(code.next(), Some('.'));
332 assert!(!code.peek_is_map(|_| true));
333 assert_eq!(code.next(), None);
334 assert!(!code.peek_is_map(|_| true));
335 }
336
337 #[test]
338 fn span() {
339 let code = common();
340
341 unsafe {
343 assert_eq!(code.next(), Some('T'));
344 assert_eq!(code.next(), Some('e'));
345 assert_eq!(code.span(), Span::new_single(2));
346 assert_eq!(code.next(), Some('s'));
347 assert_eq!(code.next(), Some('t'));
348 assert_eq!(code.next(), Some('i'));
349 assert_eq!(code.span(), Span::new_single(5));
350 assert_eq!(code.next(), Some('n'));
351 assert_eq!(code.next(), Some('g'));
352 assert_eq!(code.span(), Span::new_single(7));
353 assert_eq!(code.span(), Span::new_single(7));
354 assert_eq!(code.next(), Some('.'));
355 assert_eq!(code.span(), Span::new_empty(8));
356 assert_eq!(code.next(), None);
357 assert_eq!(code.span(), Span::new_empty(8));
358 }
359 }
360
361 #[test]
363 fn meta() {
364 let mut result = LexerResult::<_, ()>::new();
365
366 unsafe {
368 let bloo = Token::new("bloo", Span::new(0, 4));
369 let ploo = Token::new("ploo", Span::new(4, 4));
370
371 result.push_token(bloo.clone());
372 result.push_token(ploo.clone());
373
374 let result = result.finalize();
375
376 assert_eq!(result.notifications.into_sorted_vec(), vec![]);
377
378 assert_eq!(result.tokens, vec![bloo, ploo]);
379 }
380 }
381}