1use std::hash::{Hash, Hasher};
4use std::ops::{Deref, DerefMut};
5
6use crate::models::{
7 meta::{MetaTypes, TypeEq},
8 schema::xs::{
9 BasicNamespaceListType, FormChoiceType, NamespaceListType, ProcessContentsType,
10 QnameListAType, Use,
11 },
12 Ident,
13};
14
15#[derive(Debug, Clone)]
17pub struct AttributeMeta {
18 pub ident: Ident,
20
21 pub variant: AttributeMetaVariant,
23
24 pub use_: Use,
26
27 pub form: FormChoiceType,
29
30 pub default: Option<String>,
32
33 pub display_name: Option<String>,
35
36 pub documentation: Vec<String>,
38}
39
40#[derive(Debug, Clone)]
44pub enum AttributeMetaVariant {
45 Any(AnyAttributeMeta),
47
48 Type(Ident),
50}
51
52#[allow(missing_docs)]
55#[derive(Debug, Clone, Eq, PartialEq)]
56pub struct AnyAttributeMeta {
57 pub id: Option<String>,
58 pub namespace: Option<NamespaceListType>,
59 pub not_q_name: Option<QnameListAType>,
60 pub not_namespace: Option<BasicNamespaceListType>,
61 pub process_contents: ProcessContentsType,
62}
63
64#[derive(Default, Debug, Clone)]
66pub struct AttributesMeta(Vec<AttributeMeta>);
67
68impl AttributeMeta {
71 #[must_use]
73 pub fn new(ident: Ident, type_: Ident, form: FormChoiceType) -> Self {
74 Self {
75 ident,
76 variant: AttributeMetaVariant::Type(type_),
77 use_: Use::Optional,
78 form,
79 default: None,
80 display_name: None,
81 documentation: Vec::new(),
82 }
83 }
84
85 #[must_use]
87 pub fn any(ident: Ident, any: AnyAttributeMeta) -> Self {
88 Self {
89 ident,
90 variant: AttributeMetaVariant::Any(any),
91 use_: Use::Required,
92 form: FormChoiceType::Unqualified,
93 default: None,
94 display_name: None,
95 documentation: Vec::new(),
96 }
97 }
98
99 #[must_use]
101 pub fn with_use(mut self, use_: Use) -> Self {
102 self.use_ = use_;
103
104 self
105 }
106
107 #[must_use]
109 pub fn is_any(&self) -> bool {
110 matches!(&self.variant, AttributeMetaVariant::Any(_))
111 }
112
113 #[must_use]
115 pub fn as_any(&self) -> Option<&AnyAttributeMeta> {
116 if let AttributeMetaVariant::Any(any) = &self.variant {
117 Some(any)
118 } else {
119 None
120 }
121 }
122}
123
124impl TypeEq for AttributeMeta {
125 fn type_hash<H: Hasher>(&self, hasher: &mut H, types: &MetaTypes) {
126 let Self {
127 ident,
128 variant,
129 use_,
130 form,
131 default,
132 display_name,
133 documentation,
134 } = self;
135
136 ident.hash(hasher);
137 variant.type_hash(hasher, types);
138 use_.hash(hasher);
139 form.hash(hasher);
140 default.hash(hasher);
141 display_name.hash(hasher);
142 documentation.hash(hasher);
143 }
144
145 fn type_eq(&self, other: &Self, types: &MetaTypes) -> bool {
146 let Self {
147 ident,
148 variant: type_,
149 use_,
150 form,
151 default,
152 display_name,
153 documentation,
154 } = self;
155
156 ident.eq(&other.ident)
157 && type_.type_eq(&other.variant, types)
158 && use_.eq(&other.use_)
159 && form.eq(&other.form)
160 && default.eq(&other.default)
161 && display_name.eq(&other.display_name)
162 && documentation.eq(&other.documentation)
163 }
164}
165
166impl Deref for AttributesMeta {
169 type Target = Vec<AttributeMeta>;
170
171 fn deref(&self) -> &Self::Target {
172 &self.0
173 }
174}
175
176impl DerefMut for AttributesMeta {
177 fn deref_mut(&mut self) -> &mut Self::Target {
178 &mut self.0
179 }
180}
181
182impl TypeEq for AttributesMeta {
183 fn type_hash<H: Hasher>(&self, hasher: &mut H, types: &MetaTypes) {
184 TypeEq::type_hash_slice(&self.0, hasher, types);
185 }
186
187 fn type_eq(&self, other: &Self, types: &MetaTypes) -> bool {
188 TypeEq::type_eq_iter(self.0.iter(), other.0.iter(), types)
189 }
190}
191
192impl TypeEq for AttributeMetaVariant {
195 fn type_hash<H: Hasher>(&self, hasher: &mut H, types: &MetaTypes) {
196 match self {
197 Self::Any(x) => {
198 hasher.write_u8(0);
199 x.hash(hasher);
200 }
201 Self::Type(x) => {
202 hasher.write_u8(1);
203 x.type_hash(hasher, types);
204 }
205 }
206 }
207
208 fn type_eq(&self, other: &Self, types: &MetaTypes) -> bool {
209 match (self, other) {
210 (Self::Any(a), Self::Any(b)) => a.eq(b),
211 (Self::Type(a), Self::Type(b)) => a.type_eq(b, types),
212 (_, _) => false,
213 }
214 }
215}
216
217impl Hash for AnyAttributeMeta {
220 fn hash<H: Hasher>(&self, hasher: &mut H) {
221 self.id.hash(hasher);
225 }
226}