1use alloc::string::String;
8use core::fmt;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum XmlError {
16 InvalidXml(String),
20
21 MissingRequiredElement(String),
25
26 UnknownElement(String),
31
32 BadEnum(String),
38
39 CircularInheritance(String),
46
47 ValueOutOfRange(String),
53
54 LimitExceeded(String),
61
62 UnresolvedReference(String),
68}
69
70impl fmt::Display for XmlError {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 match self {
73 Self::InvalidXml(msg) => write!(f, "invalid XML: {msg}"),
74 Self::MissingRequiredElement(name) => {
75 write!(f, "missing required element <{name}>")
76 }
77 Self::UnknownElement(name) => write!(f, "unknown element <{name}>"),
78 Self::BadEnum(value) => write!(f, "invalid enum value `{value}`"),
79 Self::CircularInheritance(chain) => {
80 write!(f, "circular base_name inheritance: {chain}")
81 }
82 Self::ValueOutOfRange(msg) => write!(f, "value out of range: {msg}"),
83 Self::LimitExceeded(msg) => write!(f, "DoS limit exceeded: {msg}"),
84 Self::UnresolvedReference(name) => write!(f, "unresolved reference `{name}`"),
85 }
86 }
87}
88
89#[cfg(feature = "std")]
90impl std::error::Error for XmlError {}
91
92#[cfg(test)]
93#[allow(clippy::expect_used, clippy::unwrap_used, clippy::panic)]
94mod tests {
95 use super::*;
96 use alloc::string::ToString;
97
98 #[test]
99 fn display_invalid_xml() {
100 let e = XmlError::InvalidXml("unexpected token".into());
101 assert_eq!(e.to_string(), "invalid XML: unexpected token");
102 }
103
104 #[test]
105 fn display_missing_required() {
106 let e = XmlError::MissingRequiredElement("qos_profile".into());
107 assert_eq!(e.to_string(), "missing required element <qos_profile>");
108 }
109
110 #[test]
111 fn display_unknown_element() {
112 let e = XmlError::UnknownElement("foo".into());
113 assert_eq!(e.to_string(), "unknown element <foo>");
114 }
115
116 #[test]
117 fn display_bad_enum() {
118 let e = XmlError::BadEnum("WRONG".into());
119 assert_eq!(e.to_string(), "invalid enum value `WRONG`");
120 }
121
122 #[test]
123 fn display_circular() {
124 let e = XmlError::CircularInheritance("A -> B -> A".into());
125 assert_eq!(e.to_string(), "circular base_name inheritance: A -> B -> A");
126 }
127
128 #[test]
129 fn display_value_out_of_range() {
130 let e = XmlError::ValueOutOfRange("long > 0x7fffffff".into());
131 assert_eq!(e.to_string(), "value out of range: long > 0x7fffffff");
132 }
133
134 #[test]
135 fn display_limit_exceeded() {
136 let e = XmlError::LimitExceeded("seq > 1024".into());
137 assert_eq!(e.to_string(), "DoS limit exceeded: seq > 1024");
138 }
139
140 #[test]
141 fn equality_and_clone() {
142 let a = XmlError::InvalidXml("x".into());
143 let b = a.clone();
144 assert_eq!(a, b);
145 }
146
147 #[test]
148 fn display_unresolved_reference() {
149 let e = XmlError::UnresolvedReference("MissingProfile".into());
150 assert_eq!(e.to_string(), "unresolved reference `MissingProfile`");
151 }
152}