rimu_parse/
error.rs

1use chumsky::error::SimpleReason;
2use rimu_meta::ErrorReport;
3
4use crate::compiler::CompilerError;
5use crate::lexer::lines::LinesLexerError;
6use crate::lexer::LexerError;
7
8#[derive(Debug)]
9pub enum Error {
10    Lexer(LexerError),
11    Compiler(CompilerError),
12}
13
14impl From<Error> for ErrorReport {
15    fn from(value: Error) -> Self {
16        match value {
17            Error::Lexer(LexerError::Lines(error)) => match error {
18                LinesLexerError::InconsistentLeadingWhitespace {
19                    span,
20                    found,
21                    expected,
22                } => ErrorReport {
23                    message: "Lexer: Inconsistent leading whitespace".into(),
24                    span: span.clone(),
25                    labels: vec![(
26                        span.clone(),
27                        format!(
28                            "Found {} spaces, expected one of {} spaces.",
29                            found,
30                            expected
31                                .iter()
32                                .map(ToString::to_string)
33                                .collect::<Vec<String>>()
34                                .join(",")
35                        ),
36                    )],
37                    notes: vec![],
38                },
39            },
40            Error::Lexer(LexerError::Line(error)) => ErrorReport {
41                message: "Lexer: Unexpected character".into(),
42                span: error.span(),
43                labels: if let SimpleReason::Custom(msg) = error.reason() {
44                    vec![(error.span(), msg.to_string())]
45                } else {
46                    vec![(error.span(), format!("{}", error))]
47                },
48                notes: if let Some(e) = error.label() {
49                    vec![format!("Label is `{}`", e)]
50                } else {
51                    vec![]
52                },
53            },
54            Error::Compiler(error) => ErrorReport {
55                message: "Compiler: Unexpected token".into(),
56                span: error.span(),
57                labels: if let SimpleReason::Custom(msg) = error.reason() {
58                    vec![(error.span(), msg.to_string())]
59                } else {
60                    vec![(error.span(), format!("{}", error))]
61                },
62                notes: if let Some(e) = error.label() {
63                    vec![format!("Label is `{}`", e)]
64                } else {
65                    vec![]
66                },
67            },
68        }
69    }
70}