Skip to main content

oxyl_diagnostics/
lex_error.rs

1/// An error produced during lexing.
2///
3/// Stored inside [`LexResult`] so the caller can handle all the errors after 
4/// tokenisation rather than stopping at the first problem.
5
6use crate::{DiagSpan, Diagnostic};
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum LexError {
10    /// A lone backslash at the very end of the file with nothing after it.
11    UnexpectedEndAfterBackslash { pos: usize },
12    /// A UTF-8 character outside the ASCII range was encountered. Full 
13    /// Unicode support is planned; for now we record the byte position.
14    NonAsciiChar { pos: usize, ch: char },
15}
16
17impl std::fmt::Display for LexError {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        match self {
20            LexError::UnexpectedEndAfterBackslash { pos } => {
21                write!(f, "unexpected end of input after '\\' at byte {pos}")
22            }
23            LexError::NonAsciiChar { pos, ch } => {
24                write!(f, "non-ASCII character '{ch}' at byte {pos} (Unicode support coming soon!)")
25            }
26        }
27    }
28}
29
30impl From<LexError> for Diagnostic {
31    fn from(e: LexError) -> Self {
32        let span = match e {
33            LexError::UnexpectedEndAfterBackslash { pos } => DiagSpan::new(pos, pos + 1),
34            LexError::NonAsciiChar {pos, .. } => DiagSpan::new(pos, pos + 1),
35        };
36        Diagnostic::error("E010", e.to_string()).with_span(span)
37    }
38}