1use thiserror::Error;
4
5#[derive(Debug, Error)]
7pub enum ParseError {
8 #[error("XML parsing error: {0}")]
10 Xml(#[from] quick_xml::Error),
11
12 #[error("missing required attribute '{attribute}' on element '{element}'")]
14 MissingAttribute {
15 element: String,
17 attribute: String,
19 },
20
21 #[error("invalid value '{value}' for attribute '{attribute}' on element '{element}'")]
23 InvalidAttribute {
24 element: String,
26 attribute: String,
28 value: String,
30 },
31
32 #[error("unknown element '{element}' in context '{context}'")]
34 UnknownElement {
35 element: String,
37 context: String,
39 },
40
41 #[error("unknown type '{type_name}' referenced in field '{field}'")]
43 UnknownType {
44 type_name: String,
46 field: String,
48 },
49
50 #[error("duplicate {kind} definition: '{name}'")]
52 DuplicateDefinition {
53 kind: String,
55 name: String,
57 },
58
59 #[error("invalid schema structure: {message}")]
61 InvalidStructure {
62 message: String,
64 },
65
66 #[error("IO error: {0}")]
68 Io(#[from] std::io::Error),
69
70 #[error("UTF-8 error: {0}")]
72 Utf8(#[from] std::str::Utf8Error),
73}
74
75#[derive(Debug, Error)]
77pub enum SchemaError {
78 #[error("parse error: {0}")]
80 Parse(#[from] ParseError),
81
82 #[error("type '{name}' not found")]
84 TypeNotFound {
85 name: String,
87 },
88
89 #[error("message '{name}' not found")]
91 MessageNotFound {
92 name: String,
94 },
95
96 #[error(
98 "invalid field offset: field '{field}' at offset {offset} overlaps with previous field"
99 )]
100 InvalidOffset {
101 field: String,
103 offset: usize,
105 },
106
107 #[error(
109 "block length mismatch for message '{message}': declared {declared}, calculated {calculated}"
110 )]
111 BlockLengthMismatch {
112 message: String,
114 declared: u16,
116 calculated: u16,
118 },
119
120 #[error("circular type reference detected: {path}")]
122 CircularReference {
123 path: String,
125 },
126
127 #[error("invalid enum value '{value}' for enum '{enum_name}'")]
129 InvalidEnumValue {
130 enum_name: String,
132 value: String,
134 },
135
136 #[error("validation error: {message}")]
138 Validation {
139 message: String,
141 },
142}
143
144impl ParseError {
145 pub fn missing_attr(element: impl Into<String>, attribute: impl Into<String>) -> Self {
147 Self::MissingAttribute {
148 element: element.into(),
149 attribute: attribute.into(),
150 }
151 }
152
153 pub fn invalid_attr(
155 element: impl Into<String>,
156 attribute: impl Into<String>,
157 value: impl Into<String>,
158 ) -> Self {
159 Self::InvalidAttribute {
160 element: element.into(),
161 attribute: attribute.into(),
162 value: value.into(),
163 }
164 }
165
166 pub fn unknown_element(element: impl Into<String>, context: impl Into<String>) -> Self {
168 Self::UnknownElement {
169 element: element.into(),
170 context: context.into(),
171 }
172 }
173
174 pub fn duplicate(kind: impl Into<String>, name: impl Into<String>) -> Self {
176 Self::DuplicateDefinition {
177 kind: kind.into(),
178 name: name.into(),
179 }
180 }
181}