1use std::hash::{Hash, Hasher};
4use std::ops::{Deref, DerefMut};
5
6use crate::models::{
7 schema::{
8 xs::{
9 FormChoiceType, NamespaceListType, NotNamespaceType, ProcessContentsType, QnameListType,
10 },
11 MaxOccurs, MinOccurs,
12 },
13 Ident,
14};
15
16use super::{MetaTypes, TypeEq};
17
18#[derive(Debug, Clone)]
20pub struct ElementMeta {
21 pub ident: Ident,
23
24 pub variant: ElementMetaVariant,
26
27 pub form: FormChoiceType,
29
30 pub nillable: bool,
32
33 pub min_occurs: MinOccurs,
35
36 pub max_occurs: MaxOccurs,
38
39 pub display_name: Option<String>,
41
42 pub documentation: Vec<String>,
44}
45
46#[derive(Debug, Clone)]
50pub enum ElementMetaVariant {
51 Text,
53
54 Any {
56 meta: AnyMeta,
58 },
59
60 Type {
62 type_: Ident,
64
65 mode: ElementMode,
67 },
68}
69
70#[allow(missing_docs)]
73#[derive(Debug, Clone, Eq, PartialEq)]
74pub struct AnyMeta {
75 pub id: Option<String>,
76 pub namespace: Option<NamespaceListType>,
77 pub not_q_name: Option<QnameListType>,
78 pub not_namespace: Option<NotNamespaceType>,
79 pub process_contents: ProcessContentsType,
80}
81
82#[derive(Default, Debug, Clone)]
84pub struct ElementsMeta(pub Vec<ElementMeta>);
85
86#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
88pub enum ElementMode {
89 Element,
91
92 Group,
94}
95
96impl ElementMeta {
99 #[must_use]
102 pub fn new(ident: Ident, type_: Ident, mode: ElementMode, form: FormChoiceType) -> Self {
103 Self {
104 ident,
105 variant: ElementMetaVariant::Type { type_, mode },
106 form,
107 nillable: false,
108 min_occurs: 1,
109 max_occurs: MaxOccurs::Bounded(1),
110 display_name: None,
111 documentation: Vec::new(),
112 }
113 }
114
115 #[must_use]
117 pub fn any(ident: Ident, meta: AnyMeta) -> Self {
118 Self {
119 ident,
120 variant: ElementMetaVariant::Any { meta },
121 form: FormChoiceType::Unqualified,
122 nillable: false,
123 min_occurs: 1,
124 max_occurs: MaxOccurs::Bounded(1),
125 display_name: None,
126 documentation: Vec::new(),
127 }
128 }
129
130 #[must_use]
132 pub fn text(ident: Ident) -> Self {
133 Self {
134 ident,
135 variant: ElementMetaVariant::Text,
136 form: FormChoiceType::Unqualified,
137 nillable: false,
138 min_occurs: 1,
139 max_occurs: MaxOccurs::Bounded(1),
140 display_name: None,
141 documentation: Vec::new(),
142 }
143 }
144
145 #[must_use]
147 pub fn is_text(&self) -> bool {
148 matches!(&self.variant, ElementMetaVariant::Text)
149 }
150
151 #[must_use]
153 pub fn is_any(&self) -> bool {
154 matches!(&self.variant, ElementMetaVariant::Any { .. })
155 }
156
157 #[must_use]
159 pub fn as_any(&self) -> Option<&AnyMeta> {
160 if let ElementMetaVariant::Any { meta } = &self.variant {
161 Some(meta)
162 } else {
163 None
164 }
165 }
166}
167
168impl TypeEq for ElementMeta {
169 fn type_hash<H: Hasher>(&self, hasher: &mut H, types: &MetaTypes) {
170 let Self {
171 ident,
172 variant,
173 form,
174 nillable,
175 min_occurs,
176 max_occurs,
177 display_name,
178 documentation,
179 } = self;
180
181 ident.hash(hasher);
182 variant.type_hash(hasher, types);
183 form.hash(hasher);
184 nillable.hash(hasher);
185 min_occurs.hash(hasher);
186 max_occurs.hash(hasher);
187 display_name.hash(hasher);
188 documentation.hash(hasher);
189 }
190
191 fn type_eq(&self, other: &Self, types: &MetaTypes) -> bool {
192 let Self {
193 ident,
194 variant,
195 form,
196 nillable,
197 min_occurs,
198 max_occurs,
199 display_name,
200 documentation,
201 } = self;
202
203 ident.eq(&other.ident)
204 && variant.type_eq(&other.variant, types)
205 && form.eq(&other.form)
206 && nillable.eq(&other.nillable)
207 && min_occurs.eq(&other.min_occurs)
208 && max_occurs.eq(&other.max_occurs)
209 && display_name.eq(&other.display_name)
210 && documentation.eq(&other.documentation)
211 }
212}
213
214impl ElementsMeta {
217 pub fn push_any(&mut self, mut el: ElementMeta) {
222 let mut i = 0;
223 for element in &mut self.0 {
224 if element.is_any() && element.ident.name.is_generated() {
225 element.display_name = Some(format!("any_{i}"));
226 i += 1;
227 }
228 }
229
230 el.display_name = Some(if i > 0 {
231 format!("any_{i}")
232 } else {
233 "any".into()
234 });
235
236 self.0.push(el);
237 }
238}
239
240impl Deref for ElementsMeta {
241 type Target = Vec<ElementMeta>;
242
243 fn deref(&self) -> &Self::Target {
244 &self.0
245 }
246}
247
248impl DerefMut for ElementsMeta {
249 fn deref_mut(&mut self) -> &mut Self::Target {
250 &mut self.0
251 }
252}
253
254impl TypeEq for ElementsMeta {
255 fn type_hash<H: Hasher>(&self, hasher: &mut H, types: &MetaTypes) {
256 TypeEq::type_hash_slice(&self.0, hasher, types);
257 }
258
259 fn type_eq(&self, other: &Self, types: &MetaTypes) -> bool {
260 TypeEq::type_eq_iter(self.0.iter(), other.0.iter(), types)
261 }
262}
263
264impl TypeEq for ElementMetaVariant {
267 fn type_hash<H: Hasher>(&self, hasher: &mut H, types: &MetaTypes) {
268 match self {
269 Self::Any { meta } => {
270 hasher.write_u8(0);
271 meta.hash(hasher);
272 }
273 Self::Type { type_, mode } => {
274 hasher.write_u8(1);
275 type_.type_hash(hasher, types);
276 mode.hash(hasher);
277 }
278 Self::Text => hasher.write_u8(2),
279 }
280 }
281
282 fn type_eq(&self, other: &Self, types: &MetaTypes) -> bool {
283 match (self, other) {
284 (Self::Any { meta: a }, Self::Any { meta: b }) => a.eq(b),
285 (
286 Self::Type {
287 type_: type_a,
288 mode: mode_a,
289 },
290 Self::Type {
291 type_: type_b,
292 mode: mode_b,
293 },
294 ) => mode_a.eq(mode_b) && type_a.type_eq(type_b, types),
295 (_, _) => false,
296 }
297 }
298}
299
300impl Hash for AnyMeta {
303 fn hash<H: Hasher>(&self, hasher: &mut H) {
304 self.id.hash(hasher);
308 }
309}