1use std::borrow::Cow;
2use std::collections::HashSet;
3use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
4use std::io::Error as IoError;
5
6use anyhow::Error as AnyError;
7use thiserror::Error;
8
9use crate::types::{ElementMode, Ident, Type, Types};
10use crate::{GeneratorError, InterpreterError, ParserError};
11
12pub trait WithNamespace {
14 fn prefix() -> Option<&'static str>;
16
17 fn namespace() -> Option<&'static str>;
19}
20
21pub trait AsAny: core::any::Any {
23 fn as_any(&self) -> &dyn core::any::Any;
25
26 fn as_any_mut(&mut self) -> &mut dyn core::any::Any;
28}
29
30impl<X: 'static> AsAny for X {
31 fn as_any(&self) -> &dyn core::any::Any {
32 self
33 }
34
35 fn as_any_mut(&mut self) -> &mut dyn core::any::Any {
36 self
37 }
38}
39
40#[derive(Debug, Error)]
42pub enum Error {
43 #[error("IO Error: {0}")]
45 IoError(#[from] IoError),
46
47 #[error("Parser error: {0}")]
49 ParserError(ParserError<AnyError>),
50
51 #[error("Interpreter error: {0}")]
53 InterpreterError(#[from] InterpreterError),
54
55 #[error("Generator error: {0}")]
57 GeneratorError(#[from] GeneratorError),
58}
59
60impl<E> From<ParserError<E>> for Error
61where
62 AnyError: From<E>,
63{
64 fn from(value: ParserError<E>) -> Self {
65 match value {
66 ParserError::IoError(err) => Self::ParserError(ParserError::IoError(err)),
67 ParserError::XmlError(err) => Self::ParserError(ParserError::XmlError(err)),
68 ParserError::UrlParseError(err) => Self::ParserError(ParserError::UrlParseError(err)),
69 ParserError::UnableToResolve(url) => {
70 Self::ParserError(ParserError::UnableToResolve(url))
71 }
72 ParserError::Resolver(err) => {
73 Self::ParserError(ParserError::Resolver(AnyError::from(err)))
74 }
75 ParserError::InvalidFilePath(path) => {
76 Self::ParserError(ParserError::InvalidFilePath(path))
77 }
78 }
79 }
80}
81
82pub struct RawByteStr(Cow<'static, [u8]>);
84
85impl RawByteStr {
86 #[must_use]
88 pub fn from_slice(value: &[u8]) -> Self {
89 Self(Cow::Owned(value.to_owned()))
90 }
91}
92
93impl From<Vec<u8>> for RawByteStr {
94 fn from(value: Vec<u8>) -> Self {
95 Self(Cow::Owned(value))
96 }
97}
98
99impl From<&'static [u8]> for RawByteStr {
100 fn from(value: &'static [u8]) -> Self {
101 Self(Cow::Borrowed(value))
102 }
103}
104
105impl From<&'static str> for RawByteStr {
106 fn from(value: &'static str) -> Self {
107 Self(Cow::Borrowed(value.as_bytes()))
108 }
109}
110
111impl Debug for RawByteStr {
112 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
113 format_utf8_slice(&self.0, f)
114 }
115}
116
117impl Display for RawByteStr {
118 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
119 format_utf8_slice(&self.0, f)
120 }
121}
122
123pub(crate) struct TypesPrinter<'a> {
126 types: &'a Types,
127}
128
129#[derive(Default)]
130struct State {
131 level: usize,
132 visit: HashSet<Ident>,
133}
134
135impl<'a> TypesPrinter<'a> {
136 pub(crate) fn new(types: &'a Types) -> Self {
137 Self { types }
138 }
139
140 fn print_all(&self, f: &mut Formatter<'_>, s: &mut State) -> FmtResult {
141 for (ident, ty) in &**self.types {
142 self.print_type(f, s, ident, ty)?;
143 }
144
145 Ok(())
146 }
147
148 fn resolve_complex_type(
149 &self,
150 f: &mut Formatter<'_>,
151 s: &mut State,
152 ident: &Ident,
153 ) -> FmtResult {
154 if let Some(x) = self.types.get(ident) {
155 self.print_type(f, s, ident, x)
156 } else {
157 writeln!(f, "NOT FOUND")?;
158
159 Ok(())
160 }
161 }
162
163 #[allow(clippy::too_many_lines)]
164 fn print_type(
165 &self,
166 f: &mut Formatter<'_>,
167 s: &mut State,
168 ident: &Ident,
169 ty: &Type,
170 ) -> FmtResult {
171 macro_rules! indent {
172 ($( $tt:tt )*) => {{
173 write!(f, "{0:1$}", "", 4 * s.level)?;
174 write!(f, $( $tt )*)?;
175 }};
176 }
177 macro_rules! indentln {
178 ($( $tt:tt )*) => {{
179 write!(f, "{0:1$}", "", 4 * s.level)?;
180 writeln!(f, $( $tt )*)?;
181 }};
182 }
183
184 if !s.visit.insert(ident.clone()) {
185 writeln!(f, "LOOP DETECTED ({})", ident.name)?;
186
187 return Ok(());
188 }
189
190 match ty {
191 Type::BuildIn(x) => {
192 writeln!(f, "{}: BuildIn", ident)?;
193
194 s.level += 1;
195
196 indentln!("type={x:?}");
197
198 s.level -= 1;
199 }
200 Type::Union(x) => {
201 writeln!(f, "{}: Union", ident)?;
202
203 s.level += 1;
204
205 indentln!("base={}", x.base);
206 indentln!("types");
207
208 s.level += 1;
209
210 for ty in &*x.types {
211 indentln!("{}", &ty.type_);
212 }
213
214 s.level -= 2;
215 }
216 Type::Reference(x) => {
217 writeln!(f, "{}: Reference", ident)?;
218
219 s.level += 1;
220
221 indentln!("min={}", x.min_occurs);
222 indentln!("max={:?}", x.max_occurs);
223 indentln!("type={}", x.type_);
224
225 s.level -= 1;
226 }
227 Type::Dynamic(x) => {
228 writeln!(f, "{}: Dynamic", ident)?;
229
230 s.level += 1;
231
232 indentln!("types");
233
234 s.level += 1;
235
236 for ty in &*x.derived_types {
237 indentln!("{}", ty);
238 }
239
240 s.level -= 2;
241 }
242 Type::Enumeration(x) => {
243 writeln!(f, "{}: Enumeration", ident)?;
244
245 s.level += 1;
246
247 indentln!("base={}", x.base);
248 indentln!("variants");
249
250 s.level += 1;
251
252 for var in &*x.variants {
253 indentln!("{}={:?}", var.ident.name, var.use_);
254 }
255
256 s.level -= 2;
257 }
258 Type::All(x) | Type::Choice(x) | Type::Sequence(x) => {
259 match ty {
260 Type::All(_) => writeln!(f, "{}: All", ident)?,
261 Type::Choice(_) => writeln!(f, "{}: Choice", ident)?,
262 Type::Sequence(_) => writeln!(f, "{}: Sequence", ident)?,
263 _ => (),
264 }
265
266 s.level += 1;
267
268 if let Some(x) = &x.any {
269 indentln!("any");
270
271 s.level += 1;
272
273 if let Some(x) = &x.min_occurs {
274 indentln!("min_occurs={x:?}");
275 }
276 if let Some(x) = &x.max_occurs {
277 indentln!("max_occurs={x:?}");
278 }
279 if let Some(x) = &x.namespace {
280 indentln!("namespace={x:?}");
281 }
282 if let Some(x) = &x.not_namespace {
283 indentln!("not_namespace={x:?}");
284 }
285 if let Some(x) = &x.not_q_name {
286 indentln!("not_q_name={x:?}");
287 }
288 if let Some(x) = &x.process_contents {
289 indentln!("process_contents={x:?}");
290 }
291
292 s.level -= 1;
293 }
294
295 for x in &*x.elements {
296 indentln!("element");
297
298 s.level += 1;
299
300 indentln!("name={}", x.ident.name);
301 indentln!("min_occurs={}", x.min_occurs);
302 indentln!("max_occurs={:?}", x.max_occurs);
303 indentln!("element_type={:?}", x.element_mode);
304
305 if x.element_mode == ElementMode::Element {
306 indentln!("type={}", x.type_);
307 } else {
308 indent!("type=");
309 self.resolve_complex_type(f, s, &x.type_)?;
310 }
311
312 s.level -= 1;
313 }
314
315 s.level -= 1;
316 }
317 Type::ComplexType(x) => {
318 writeln!(f, "{}: ComplexType", ident)?;
319
320 s.level += 1;
321
322 indentln!("base={}", x.base);
323 indentln!("min_occurs={}", x.min_occurs);
324 indentln!("max_occurs={:?}", x.max_occurs);
325 indentln!("is_dynamic={}", x.is_dynamic);
326
327 if let Some(x) = &x.any_attribute {
328 indentln!("any_attribute");
329
330 s.level += 1;
331
332 if let Some(x) = &x.namespace {
333 indentln!("namespace={x:?}");
334 }
335 if let Some(x) = &x.not_namespace {
336 indentln!("not_namespace={x:?}");
337 }
338 if let Some(x) = &x.not_q_name {
339 indentln!("not_q_name={x:?}");
340 }
341 if let Some(x) = &x.process_contents {
342 indentln!("process_contents={x:?}");
343 }
344
345 s.level -= 1;
346 }
347
348 for x in &*x.attributes {
349 indentln!("attribute");
350
351 s.level += 1;
352
353 indentln!("name={}", x.ident.name);
354 indentln!("type={}", x.type_);
355 indentln!("use={:?}", x.use_);
356 indentln!("default={:?}", x.default);
357
358 s.level -= 1;
359 }
360
361 if let Some(content) = &x.content {
362 indentln!("content");
363
364 s.level += 1;
365
366 indent!("type=");
367 self.resolve_complex_type(f, s, content)?;
368
369 s.level -= 1;
370 }
371
372 s.level -= 1;
373 }
374 }
375
376 s.visit.remove(ident);
377
378 Ok(())
379 }
380}
381
382impl Display for TypesPrinter<'_> {
383 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
384 let mut s = State::default();
385
386 self.print_all(f, &mut s)
387 }
388}
389
390pub(crate) fn format_utf8_slice(bytes: &[u8], f: &mut Formatter<'_>) -> FmtResult {
393 for byte in bytes {
394 if byte.is_ascii_control() {
395 write!(f, r"\x{byte:02x}")?;
396 } else {
397 write!(f, "{}", *byte as char)?;
398 }
399 }
400
401 Ok(())
402}