mago_codex/ttype/
error.rs

1use mago_span::HasSpan;
2use mago_span::Span;
3use serde::Serialize;
4
5use mago_type_syntax::error::ParseError;
6
7#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
8pub enum TypeError {
9    ParseError(ParseError),
10    UnsupportedType(String, Span),
11    InvalidType(String, String, Span),
12}
13
14impl std::fmt::Display for TypeError {
15    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16        match self {
17            TypeError::ParseError(err) => write!(f, "{err}"),
18            TypeError::UnsupportedType(ty, _) => {
19                write!(f, "The type `{ty}` is not supported.")
20            }
21            TypeError::InvalidType(_, message, _) => {
22                write!(f, "{message}")
23            }
24        }
25    }
26}
27
28impl TypeError {
29    #[must_use]
30    pub fn note(&self) -> String {
31        match self {
32            TypeError::ParseError(err) => err.note(),
33            TypeError::UnsupportedType(ty, _) => {
34                format!("The type `{ty}` is syntactically valid but is not yet supported.")
35            }
36            TypeError::InvalidType(ty, _, _) => {
37                format!("The type declaration `{ty}` is not valid or could not be resolved.")
38            }
39        }
40    }
41
42    #[must_use]
43    pub fn help(&self) -> String {
44        match self {
45            TypeError::ParseError(err) => err.help(),
46            TypeError::UnsupportedType(_, _) => "Try using a simpler or more standard type declaration.".to_string(),
47            TypeError::InvalidType(_, _, _) => {
48                "Check for typos or ensure the type is a valid class, interface, or built-in type.".to_string()
49            }
50        }
51    }
52}
53
54// Ensure HasSpan is implemented for TypeError to get the location of the error
55impl HasSpan for TypeError {
56    fn span(&self) -> Span {
57        match self {
58            TypeError::ParseError(err) => err.span(),
59            TypeError::UnsupportedType(_, span) | TypeError::InvalidType(_, _, span) => *span,
60        }
61    }
62}
63
64impl From<ParseError> for TypeError {
65    fn from(err: ParseError) -> Self {
66        TypeError::ParseError(err)
67    }
68}