1use core::fmt;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum CppGenError {
10 UnsupportedConstruct {
14 construct: String,
16 context: Option<String>,
18 },
19 InvalidName {
22 name: String,
24 reason: String,
26 },
27 InheritanceCycle {
30 type_name: String,
32 },
33 Internal(String),
36}
37
38impl fmt::Display for CppGenError {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 match self {
41 Self::UnsupportedConstruct { construct, context } => match context {
42 Some(ctx) => write!(
43 f,
44 "unsupported IDL construct '{construct}' in '{ctx}' (C5.1-a Foundation scope)",
45 ),
46 None => write!(
47 f,
48 "unsupported IDL construct '{construct}' (C5.1-a Foundation scope)",
49 ),
50 },
51 Self::InvalidName { name, reason } => {
52 write!(f, "invalid identifier '{name}': {reason}")
53 }
54 Self::InheritanceCycle { type_name } => {
55 write!(f, "inheritance cycle detected at type '{type_name}'")
56 }
57 Self::Internal(msg) => write!(f, "internal codegen error: {msg}"),
58 }
59 }
60}
61
62impl std::error::Error for CppGenError {}
63
64#[cfg(test)]
65mod tests {
66 #![allow(clippy::expect_used, clippy::panic)]
67 use super::*;
68
69 #[test]
70 fn unsupported_display_has_context() {
71 let e = CppGenError::UnsupportedConstruct {
72 construct: "interface".into(),
73 context: Some("Foo".into()),
74 };
75 let s = format!("{e}");
76 assert!(s.contains("interface"));
77 assert!(s.contains("Foo"));
78 }
79
80 #[test]
81 fn unsupported_display_without_context() {
82 let e = CppGenError::UnsupportedConstruct {
83 construct: "any".into(),
84 context: None,
85 };
86 let s = format!("{e}");
87 assert!(s.contains("any"));
88 }
89
90 #[test]
91 fn invalid_name_display() {
92 let e = CppGenError::InvalidName {
93 name: "class".into(),
94 reason: "reserved C++ keyword".into(),
95 };
96 assert!(format!("{e}").contains("reserved"));
97 }
98
99 #[test]
100 fn inheritance_cycle_display() {
101 let e = CppGenError::InheritanceCycle {
102 type_name: "Loop".into(),
103 };
104 assert!(format!("{e}").contains("Loop"));
105 }
106
107 #[test]
108 fn internal_display() {
109 let e = CppGenError::Internal("oops".into());
110 assert!(format!("{e}").contains("oops"));
111 }
112}