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, TypeVariant, 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 write!(f, "\"")?;
114 format_utf8_slice(&self.0, f)?;
115 write!(f, "\"")?;
116
117 Ok(())
118 }
119}
120
121impl Display for RawByteStr {
122 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
123 write!(f, "\"")?;
124 format_utf8_slice(&self.0, f)?;
125 write!(f, "\"")?;
126
127 Ok(())
128 }
129}
130
131pub(crate) struct TypesPrinter<'a> {
134 types: &'a Types,
135}
136
137#[derive(Default)]
138struct State {
139 level: usize,
140 visit: HashSet<Ident>,
141}
142
143impl<'a> TypesPrinter<'a> {
144 pub(crate) fn new(types: &'a Types) -> Self {
145 Self { types }
146 }
147
148 fn print_all(&self, f: &mut Formatter<'_>, s: &mut State) -> FmtResult {
149 for (ident, ty) in &**self.types {
150 self.print_type(f, s, ident, ty)?;
151 }
152
153 Ok(())
154 }
155
156 fn resolve_complex_type(
157 &self,
158 f: &mut Formatter<'_>,
159 s: &mut State,
160 ident: &Ident,
161 ) -> FmtResult {
162 if let Some(x) = self.types.get(ident) {
163 self.print_type(f, s, ident, x)
164 } else {
165 writeln!(f, "NOT FOUND")?;
166
167 Ok(())
168 }
169 }
170
171 #[allow(clippy::too_many_lines)]
172 fn print_type(
173 &self,
174 f: &mut Formatter<'_>,
175 s: &mut State,
176 ident: &Ident,
177 ty: &Type,
178 ) -> FmtResult {
179 macro_rules! indent {
180 ($( $tt:tt )*) => {{
181 write!(f, "{0:1$}", "", 4 * s.level)?;
182 write!(f, $( $tt )*)?;
183 }};
184 }
185 macro_rules! indentln {
186 ($( $tt:tt )*) => {{
187 write!(f, "{0:1$}", "", 4 * s.level)?;
188 writeln!(f, $( $tt )*)?;
189 }};
190 }
191
192 if !s.visit.insert(ident.clone()) {
193 writeln!(f, "LOOP DETECTED ({})", ident.name)?;
194
195 return Ok(());
196 }
197
198 match &ty.variant {
199 TypeVariant::BuildIn(x) => {
200 writeln!(f, "{}: BuildIn", ident)?;
201
202 s.level += 1;
203
204 indentln!("display_name={:?}", &ty.display_name);
205 indentln!("type={x:?}");
206
207 s.level -= 1;
208 }
209 TypeVariant::Union(x) => {
210 writeln!(f, "{}: Union", ident)?;
211
212 s.level += 1;
213
214 indentln!("display_name={:?}", &ty.display_name);
215 indentln!("base={}", x.base);
216 indentln!("types");
217
218 s.level += 1;
219
220 for ty in &*x.types {
221 indentln!("{}", &ty.type_);
222 }
223
224 s.level -= 2;
225 }
226 TypeVariant::Reference(x) => {
227 writeln!(f, "{}: Reference", ident)?;
228
229 s.level += 1;
230
231 indentln!("display_name={:?}", &ty.display_name);
232 indentln!("min={}", x.min_occurs);
233 indentln!("max={:?}", x.max_occurs);
234 indentln!("type={}", x.type_);
235
236 s.level -= 1;
237 }
238 TypeVariant::Dynamic(x) => {
239 writeln!(f, "{}: Dynamic", ident)?;
240
241 s.level += 1;
242
243 indentln!("display_name={:?}", &ty.display_name);
244 indentln!("types");
245
246 s.level += 1;
247
248 for ty in &*x.derived_types {
249 indentln!("{}", ty);
250 }
251
252 s.level -= 2;
253 }
254 TypeVariant::Enumeration(x) => {
255 writeln!(f, "{}: Enumeration", ident)?;
256
257 s.level += 1;
258
259 indentln!("display_name={:?}", &ty.display_name);
260 indentln!("base={}", x.base);
261 indentln!("variants");
262
263 s.level += 1;
264
265 for var in &*x.variants {
266 indentln!("{}={:?}", var.ident.name, var.use_);
267 }
268
269 s.level -= 2;
270 }
271 TypeVariant::All(x) | TypeVariant::Choice(x) | TypeVariant::Sequence(x) => {
272 match &ty.variant {
273 TypeVariant::All(_) => writeln!(f, "{}: All", ident)?,
274 TypeVariant::Choice(_) => writeln!(f, "{}: Choice", ident)?,
275 TypeVariant::Sequence(_) => writeln!(f, "{}: Sequence", ident)?,
276 _ => (),
277 }
278
279 s.level += 1;
280
281 indentln!("display_name={:?}", &ty.display_name);
282
283 if let Some(x) = &x.any {
284 indentln!("any");
285
286 s.level += 1;
287
288 if let Some(x) = &x.min_occurs {
289 indentln!("min_occurs={x:?}");
290 }
291 if let Some(x) = &x.max_occurs {
292 indentln!("max_occurs={x:?}");
293 }
294 if let Some(x) = &x.namespace {
295 indentln!("namespace={x:?}");
296 }
297 if let Some(x) = &x.not_namespace {
298 indentln!("not_namespace={x:?}");
299 }
300 if let Some(x) = &x.not_q_name {
301 indentln!("not_q_name={x:?}");
302 }
303 if let Some(x) = &x.process_contents {
304 indentln!("process_contents={x:?}");
305 }
306
307 s.level -= 1;
308 }
309
310 for x in &*x.elements {
311 indentln!("element");
312
313 s.level += 1;
314
315 indentln!("name={}", x.ident.name);
316 indentln!("min_occurs={}", x.min_occurs);
317 indentln!("max_occurs={:?}", x.max_occurs);
318 indentln!("element_type={:?}", x.element_mode);
319
320 if x.element_mode == ElementMode::Element {
321 indentln!("type={}", x.type_);
322 } else {
323 indent!("type=");
324 self.resolve_complex_type(f, s, &x.type_)?;
325 }
326
327 s.level -= 1;
328 }
329
330 s.level -= 1;
331 }
332 TypeVariant::ComplexType(x) => {
333 writeln!(f, "{}: ComplexType", ident)?;
334
335 s.level += 1;
336
337 indentln!("display_name={:?}", &ty.display_name);
338 indentln!("base={}", x.base);
339 indentln!("min_occurs={}", x.min_occurs);
340 indentln!("max_occurs={:?}", x.max_occurs);
341 indentln!("is_dynamic={}", x.is_dynamic);
342
343 if let Some(x) = &x.any_attribute {
344 indentln!("any_attribute");
345
346 s.level += 1;
347
348 if let Some(x) = &x.namespace {
349 indentln!("namespace={x:?}");
350 }
351 if let Some(x) = &x.not_namespace {
352 indentln!("not_namespace={x:?}");
353 }
354 if let Some(x) = &x.not_q_name {
355 indentln!("not_q_name={x:?}");
356 }
357 if let Some(x) = &x.process_contents {
358 indentln!("process_contents={x:?}");
359 }
360
361 s.level -= 1;
362 }
363
364 for x in &*x.attributes {
365 indentln!("attribute");
366
367 s.level += 1;
368
369 indentln!("name={}", x.ident.name);
370 indentln!("type={}", x.type_);
371 indentln!("use={:?}", x.use_);
372 indentln!("default={:?}", x.default);
373
374 s.level -= 1;
375 }
376
377 if let Some(content) = &x.content {
378 indentln!("content");
379
380 s.level += 1;
381
382 indent!("type=");
383 self.resolve_complex_type(f, s, content)?;
384
385 s.level -= 1;
386 }
387
388 s.level -= 1;
389 }
390 }
391
392 s.visit.remove(ident);
393
394 Ok(())
395 }
396}
397
398impl Display for TypesPrinter<'_> {
399 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
400 let mut s = State::default();
401
402 self.print_all(f, &mut s)
403 }
404}
405
406pub(crate) fn format_utf8_slice(bytes: &[u8], f: &mut Formatter<'_>) -> FmtResult {
409 for byte in bytes {
410 if byte.is_ascii_control() {
411 write!(f, r"\x{byte:02x}")?;
412 } else {
413 write!(f, "{}", *byte as char)?;
414 }
415 }
416
417 Ok(())
418}