xsd_schema/compiler/
error.rs1use crate::parser::location::SourceRef;
6use thiserror::Error;
7
8pub type NfaCompileResult<T> = Result<T, NfaCompileError>;
10
11#[derive(Error, Debug, Clone)]
13pub enum NfaCompileError {
14 #[error("unresolved group reference: {name}")]
16 UnresolvedGroupRef {
17 name: String,
18 location: Option<SourceRef>,
19 },
20
21 #[error("unresolved element reference: {name}")]
23 UnresolvedElementRef {
24 name: String,
25 location: Option<SourceRef>,
26 },
27
28 #[error("invalid occurrence: minOccurs ({min}) > maxOccurs ({max})")]
30 InvalidOccurrence {
31 min: u32,
32 max: u32,
33 location: Option<SourceRef>,
34 },
35
36 #[error("xs:all group can only contain element particles in XSD 1.0")]
38 InvalidAllGroupContent { location: Option<SourceRef> },
39
40 #[error("invalid xs:all occurrence constraint: {reason}")]
42 InvalidAllGroupOccurs {
43 reason: String,
44 location: Option<SourceRef>,
45 },
46
47 #[error("recursion limit exceeded while compiling content model")]
49 RecursionLimitExceeded { location: Option<SourceRef> },
50
51 #[error("empty content model")]
53 EmptyContentModel { location: Option<SourceRef> },
54}
55
56impl NfaCompileError {
57 pub fn unresolved_group(name: impl Into<String>, location: Option<SourceRef>) -> Self {
59 NfaCompileError::UnresolvedGroupRef {
60 name: name.into(),
61 location,
62 }
63 }
64
65 pub fn unresolved_element(name: impl Into<String>, location: Option<SourceRef>) -> Self {
67 NfaCompileError::UnresolvedElementRef {
68 name: name.into(),
69 location,
70 }
71 }
72
73 pub fn invalid_occurrence(min: u32, max: u32, location: Option<SourceRef>) -> Self {
75 NfaCompileError::InvalidOccurrence { min, max, location }
76 }
77
78 pub fn invalid_all_group(location: Option<SourceRef>) -> Self {
80 NfaCompileError::InvalidAllGroupContent { location }
81 }
82
83 pub fn invalid_all_group_occurs(
85 reason: impl Into<String>,
86 location: Option<SourceRef>,
87 ) -> Self {
88 NfaCompileError::InvalidAllGroupOccurs {
89 reason: reason.into(),
90 location,
91 }
92 }
93
94 pub fn recursion_exceeded(location: Option<SourceRef>) -> Self {
96 NfaCompileError::RecursionLimitExceeded { location }
97 }
98
99 pub fn empty_content(location: Option<SourceRef>) -> Self {
101 NfaCompileError::EmptyContentModel { location }
102 }
103
104 pub fn location(&self) -> Option<&SourceRef> {
106 match self {
107 NfaCompileError::UnresolvedGroupRef { location, .. } => location.as_ref(),
108 NfaCompileError::UnresolvedElementRef { location, .. } => location.as_ref(),
109 NfaCompileError::InvalidOccurrence { location, .. } => location.as_ref(),
110 NfaCompileError::InvalidAllGroupContent { location } => location.as_ref(),
111 NfaCompileError::InvalidAllGroupOccurs { location, .. } => location.as_ref(),
112 NfaCompileError::RecursionLimitExceeded { location } => location.as_ref(),
113 NfaCompileError::EmptyContentModel { location } => location.as_ref(),
114 }
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121
122 #[test]
123 fn test_error_messages() {
124 let err = NfaCompileError::unresolved_group("myGroup", None);
125 assert!(err.to_string().contains("myGroup"));
126
127 let err = NfaCompileError::invalid_occurrence(5, 3, None);
128 assert!(err.to_string().contains("5"));
129 assert!(err.to_string().contains("3"));
130 }
131
132 #[test]
133 fn test_location_accessor() {
134 let err = NfaCompileError::unresolved_element("elem", None);
135 assert!(err.location().is_none());
136 }
137}