1pub mod custom;
4pub mod ident;
5pub mod info;
6pub mod name;
7pub mod type_;
8
9mod helper;
10mod name_builder;
11
12use std::collections::BTreeMap;
13use std::ops::Deref;
14use std::ops::DerefMut;
15use std::sync::atomic::AtomicUsize;
16use std::sync::Arc;
17
18pub use self::custom::CustomType;
19pub use self::helper::{VecHelper, WithIdent};
20pub use self::ident::{Ident, IdentType};
21pub use self::info::{
22 AnyAttributeInfo, AnyInfo, AttributeInfo, AttributesInfo, Base, ComplexInfo, DynamicInfo,
23 ElementInfo, ElementMode, ElementsInfo, EnumerationInfo, GroupInfo, ReferenceInfo, UnionInfo,
24 UnionTypeInfo, UnionTypesInfo, VariantInfo,
25};
26pub use self::name::Name;
27pub use self::name_builder::{NameBuilder, NameFallback};
28pub use self::type_::{BuildInInfo, Type, TypeEq, TypeVariant};
29
30use crate::schema::{Namespace, NamespaceId};
31
32#[derive(Default, Debug)]
38pub struct Types {
39 pub types: BTreeMap<Ident, Type>,
41
42 pub modules: BTreeMap<NamespaceId, Module>,
44
45 next_name_id: Arc<AtomicUsize>,
46}
47
48#[derive(Debug)]
50pub struct Module {
51 pub name: Option<Name>,
53
54 pub namespace: Option<Namespace>,
56}
57
58impl Types {
59 pub fn name_builder(&mut self) -> NameBuilder {
61 NameBuilder::new(self.next_name_id.clone())
62 }
63
64 #[must_use]
71 pub fn get_resolved<'a>(&'a self, ident: &'a Ident) -> Option<(&'a Ident, &'a Type)> {
72 let mut visit = Vec::new();
73
74 get_resolved_impl(self, ident, &mut visit)
75 }
76
77 #[must_use]
82 pub fn get_resolved_type<'a>(&'a self, ident: &'a Ident) -> Option<&'a Type> {
83 self.get_resolved(ident).map(|(_ident, ty)| ty)
84 }
85
86 #[must_use]
91 pub fn get_resolved_ident<'a>(&'a self, ident: &'a Ident) -> Option<&'a Ident> {
92 self.get_resolved(ident).map(|(ident, _ty)| ident)
93 }
94
95 #[inline]
99 #[must_use]
100 pub fn get_variant(&self, ident: &Ident) -> Option<&TypeVariant> {
101 self.get(ident).map(|ty| &ty.variant)
102 }
103
104 #[inline]
108 #[must_use]
109 pub fn get_variant_mut(&mut self, ident: &Ident) -> Option<&mut TypeVariant> {
110 self.get_mut(ident).map(|ty| &mut ty.variant)
111 }
112}
113
114impl Deref for Types {
115 type Target = BTreeMap<Ident, Type>;
116
117 fn deref(&self) -> &Self::Target {
118 &self.types
119 }
120}
121
122impl DerefMut for Types {
123 fn deref_mut(&mut self) -> &mut Self::Target {
124 &mut self.types
125 }
126}
127
128fn get_resolved_impl<'a>(
129 types: &'a Types,
130 ident: &'a Ident,
131 visited: &mut Vec<&'a Ident>,
132) -> Option<(&'a Ident, &'a Type)> {
133 if visited.contains(&ident) {
134 let chain = visited
135 .iter()
136 .map(ToString::to_string)
137 .chain(Some(ident.to_string()))
138 .collect::<Vec<_>>()
139 .join(" >> ");
140
141 tracing::debug!("Detected type reference loop: {chain}");
142
143 return None;
144 }
145
146 let ty = types.get(ident)?;
147
148 match &ty.variant {
149 TypeVariant::Reference(x) if x.is_single() => {
150 visited.push(ident);
151
152 let ret = match get_resolved_impl(types, &x.type_, visited) {
153 None => Some((ident, ty)),
154 Some((ident, ty)) => Some((ident, ty)),
155 };
156
157 visited.pop();
158
159 ret
160 }
161 _ => Some((ident, ty)),
162 }
163}