1use miette::Diagnostic;
4use thiserror::Error;
5
6#[derive(Error, Debug, Diagnostic)]
8pub enum GenError {
9 #[error("Invalid identifier: '{identifier}'{}", suggestion.as_ref().map(|s| format!(" - {}", s)).unwrap_or_default())]
11 #[diagnostic(code(fob::gen::invalid_identifier))]
12 InvalidIdentifier {
13 identifier: String,
14 suggestion: Option<String>,
15 },
16
17 #[error("Code generation failed: {context}{}", reason.as_ref().map(|r| format!(" - {}", r)).unwrap_or_default())]
19 #[diagnostic(code(fob::gen::codegen_failed))]
20 CodegenFailed {
21 context: String,
22 reason: Option<String>,
23 },
24
25 #[error("Invalid AST structure: {node_type}{}", details.as_ref().map(|d| format!(" - {}", d)).unwrap_or_default())]
27 #[diagnostic(code(fob::gen::invalid_ast))]
28 InvalidAst {
29 node_type: String,
30 details: Option<String>,
31 },
32}
33
34impl GenError {
35 pub fn invalid_identifier(identifier: impl Into<String>) -> Self {
37 Self::InvalidIdentifier {
38 identifier: identifier.into(),
39 suggestion: None,
40 }
41 }
42
43 pub fn codegen_failed(context: impl Into<String>) -> Self {
45 Self::CodegenFailed {
46 context: context.into(),
47 reason: None,
48 }
49 }
50
51 pub fn codegen_failed_with_reason(
53 context: impl Into<String>,
54 reason: impl Into<String>,
55 ) -> Self {
56 Self::CodegenFailed {
57 context: context.into(),
58 reason: Some(reason.into()),
59 }
60 }
61
62 pub fn invalid_ast(node_type: impl Into<String>) -> Self {
64 Self::InvalidAst {
65 node_type: node_type.into(),
66 details: None,
67 }
68 }
69}
70
71pub type Result<T> = std::result::Result<T, GenError>;