xsd_parser/optimizer/
mod.rs

1//! The `optimizer` module contains the type information [`Optimizer`] and all related types.
2
3mod dynamic_to_choice;
4mod empty_enums;
5mod empty_unions;
6mod flatten_complex_type;
7mod flatten_unions;
8mod merge_choice_cardinality;
9mod merge_enum_unions;
10mod misc;
11mod remove_duplicates;
12mod resolve_typedefs;
13mod unrestricted_base;
14
15use thiserror::Error;
16
17use crate::types::{Ident, Types};
18
19use self::misc::{BaseMap, TypedefMap};
20
21/// The [`Optimizer`] is a structure that can be used to reduce the size and the
22/// complexity of a [`Types`] instance.
23///
24/// The optimizer contains different optimizations that could be applied to a
25/// [`Types`] instance. Optimizations are usually used to reduce the size or the
26/// complexity of the different types.
27#[must_use]
28#[derive(Debug)]
29pub struct Optimizer {
30    types: Types,
31    bases: Option<BaseMap>,
32    typedefs: Option<TypedefMap>,
33}
34
35/// Error that is raised by the [`Optimizer`].
36#[derive(Error, Debug)]
37pub enum Error {
38    /// Unknown type identifier.
39    ///
40    /// Is raised if a specific identifier could not be resolved to it's
41    /// corresponding type information.
42    #[error("Unknown type identifier: {0}!")]
43    UnknownType(Ident),
44
45    /// The type is not a union type.
46    ///
47    /// Is raised if a type is expected to be a union, but it is not.
48    #[error("The type is not a union type: {0}!")]
49    ExpectedUnion(Ident),
50
51    /// The type is not a complex choice type.
52    ///
53    /// Is raised if a type is expected to be a complex choice, but it is not.
54    #[error("The type is not a complex choice type: {0}!")]
55    ExpectedComplexChoice(Ident),
56
57    /// The type is not a complex type.
58    ///
59    /// Is raised if a type is expected to be a complex type, but it is not.
60    #[error("The type is not a complex type: {0}!")]
61    ExpectedComplexType(Ident),
62
63    /// The complex type is missing a content type.
64    ///
65    /// Is raised if the content type of a complex type could not be resolved.
66    #[error("Complex type {0} is missing a content type!")]
67    MissingContentType(Ident),
68}
69
70macro_rules! get_bases {
71    ($this:expr) => {{
72        if $this.bases.is_none() {
73            $this.bases = Some(crate::optimizer::BaseMap::new(&$this.types));
74        }
75
76        $this.bases.as_ref().unwrap()
77    }};
78}
79
80macro_rules! get_typedefs {
81    ($this:expr) => {{
82        if $this.typedefs.is_none() {
83            $this.typedefs = Some(crate::optimizer::TypedefMap::new(&$this.types));
84        }
85
86        $this.typedefs.as_ref().unwrap()
87    }};
88}
89
90pub(super) use get_bases;
91pub(super) use get_typedefs;
92
93impl Optimizer {
94    /// Create a new [`Optimizer`] instance from the passed `types`.
95    pub fn new(types: Types) -> Self {
96        Self {
97            types,
98            bases: None,
99            typedefs: None,
100        }
101    }
102
103    /// Finish the optimization and return the resulting [`Types`].
104    #[must_use]
105    pub fn finish(self) -> Types {
106        self.types
107    }
108}