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}