zerodds_idl_csharp/
error.rs1use core::fmt;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum CsGenError {
10 UnsupportedConstruct {
15 construct: String,
17 context: Option<String>,
19 },
20 InvalidName {
26 name: String,
28 reason: String,
30 },
31 InheritanceCycle {
34 type_name: String,
36 },
37 Internal(String),
40}
41
42impl fmt::Display for CsGenError {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 match self {
45 Self::UnsupportedConstruct { construct, context } => match context {
46 Some(ctx) => write!(
47 f,
48 "unsupported IDL construct '{construct}' in '{ctx}' (C5.3-a Foundation scope)",
49 ),
50 None => write!(
51 f,
52 "unsupported IDL construct '{construct}' (C5.3-a Foundation scope)",
53 ),
54 },
55 Self::InvalidName { name, reason } => {
56 write!(f, "invalid identifier '{name}': {reason}")
57 }
58 Self::InheritanceCycle { type_name } => {
59 write!(f, "inheritance cycle detected at type '{type_name}'")
60 }
61 Self::Internal(msg) => write!(f, "internal codegen error: {msg}"),
62 }
63 }
64}
65
66impl std::error::Error for CsGenError {}
67
68#[cfg(test)]
69mod tests {
70 #![allow(clippy::expect_used, clippy::panic)]
71 use super::*;
72
73 #[test]
74 fn unsupported_display_has_context() {
75 let e = CsGenError::UnsupportedConstruct {
76 construct: "interface".into(),
77 context: Some("Foo".into()),
78 };
79 let s = format!("{e}");
80 assert!(s.contains("interface"));
81 assert!(s.contains("Foo"));
82 }
83
84 #[test]
85 fn unsupported_display_without_context() {
86 let e = CsGenError::UnsupportedConstruct {
87 construct: "any".into(),
88 context: None,
89 };
90 let s = format!("{e}");
91 assert!(s.contains("any"));
92 }
93
94 #[test]
95 fn invalid_name_display() {
96 let e = CsGenError::InvalidName {
97 name: "@@".into(),
98 reason: "double-escape not allowed".into(),
99 };
100 assert!(format!("{e}").contains("double-escape"));
101 }
102
103 #[test]
104 fn inheritance_cycle_display() {
105 let e = CsGenError::InheritanceCycle {
106 type_name: "Loop".into(),
107 };
108 assert!(format!("{e}").contains("Loop"));
109 }
110
111 #[test]
112 fn internal_display() {
113 let e = CsGenError::Internal("oops".into());
114 assert!(format!("{e}").contains("oops"));
115 }
116
117 #[test]
118 fn errors_are_clonable_and_eq() {
119 let e1 = CsGenError::Internal("x".into());
120 let e2 = e1.clone();
121 assert_eq!(e1, e2);
122 }
123}