1use sup_xml_core::error::XmlError;
10
11#[derive(Debug)]
12pub enum XsltError {
13 InvalidStylesheet(String),
17
18 UnresolvedReference(String),
22
23 Xpath(XmlError),
25
26 Terminated(String),
29}
30
31impl std::fmt::Display for XsltError {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 match self {
34 XsltError::InvalidStylesheet(msg) => write!(f, "invalid stylesheet: {msg}"),
35 XsltError::UnresolvedReference(msg) => write!(f, "unresolved reference: {msg}"),
36 XsltError::Xpath(e) => write!(f, "xpath error: {}", e.message),
37 XsltError::Terminated(msg) => write!(f, "xsl:message terminate=yes: {msg}"),
38 }
39 }
40}
41
42impl std::error::Error for XsltError {}
43
44impl From<XmlError> for XsltError {
45 fn from(e: XmlError) -> Self { XsltError::Xpath(e) }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51 use sup_xml_core::error::{ErrorDomain, ErrorLevel};
52
53 #[test]
54 fn display_invalid_stylesheet() {
55 let e = XsltError::InvalidStylesheet("bad <foo>".into());
56 assert_eq!(format!("{e}"), "invalid stylesheet: bad <foo>");
57 }
58
59 #[test]
60 fn display_unresolved_reference() {
61 let e = XsltError::UnresolvedReference("template X".into());
62 assert_eq!(format!("{e}"), "unresolved reference: template X");
63 }
64
65 #[test]
66 fn display_xpath_wraps_inner_message() {
67 let inner = XmlError::new(ErrorDomain::XPath, ErrorLevel::Error, "syntax");
68 let e = XsltError::Xpath(inner);
69 assert_eq!(format!("{e}"), "xpath error: syntax");
70 }
71
72 #[test]
73 fn display_terminated() {
74 let e = XsltError::Terminated("user-requested halt".into());
75 assert_eq!(format!("{e}"), "xsl:message terminate=yes: user-requested halt");
76 }
77
78 #[test]
79 fn from_xml_error_wraps_as_xpath() {
80 let inner = XmlError::new(ErrorDomain::XPath, ErrorLevel::Error, "div by zero");
81 let e: XsltError = inner.into();
82 assert!(matches!(e, XsltError::Xpath(_)));
83 assert_eq!(format!("{e}"), "xpath error: div by zero");
84 }
85
86 #[test]
87 fn implements_std_error_trait() {
88 let e = XsltError::InvalidStylesheet("x".into());
90 let err: &dyn std::error::Error = &e;
91 assert!(err.to_string().contains("invalid stylesheet"));
92 }
93
94 #[test]
95 fn debug_format_works() {
96 let e = XsltError::Terminated("x".into());
99 let s = format!("{e:?}");
100 assert!(s.contains("Terminated"));
101 }
102}