1use std::fmt::{Display, Formatter, Result as FmtResult};
4use std::hash::Hash;
5
6use crate::models::schema::{NamespaceId, SchemaId};
7
8use super::Name;
9
10#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
12pub struct TypeIdent {
13 pub ns: NamespaceId,
15
16 pub schema: SchemaId,
22
23 pub name: Name,
25
26 pub type_: TypeIdentType,
28}
29
30pub type TypeIdentType = IdentType;
32
33#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
36pub struct PropertyIdent {
37 pub ns: NamespaceId,
39
40 pub name: Name,
42}
43
44pub type ElementIdent = PropertyIdent;
47
48pub type AttributeIdent = PropertyIdent;
51
52pub type EnumerationIdent = PropertyIdent;
56
57#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
59pub enum IdentType {
60 Type = 0,
62
63 Group = 1,
65
66 Element = 2,
68
69 ElementType = 3,
71
72 Attribute = 4,
74
75 AttributeGroup = 5,
77
78 BuildIn = 6,
80
81 Enumeration = 7,
83
84 NillableContent = 8,
86
87 DynamicElement = 9,
89}
90
91#[allow(missing_docs)]
94impl TypeIdent {
95 pub const UNKNOWN: Self = Self::type_("UNKNOWN");
96
97 pub const U8: Self = Self::build_in("u8");
98 pub const U16: Self = Self::build_in("u16");
99 pub const U32: Self = Self::build_in("u32");
100 pub const U64: Self = Self::build_in("u64");
101 pub const U128: Self = Self::build_in("u128");
102 pub const USIZE: Self = Self::build_in("usize");
103
104 pub const I8: Self = Self::build_in("i8");
105 pub const I16: Self = Self::build_in("i16");
106 pub const I32: Self = Self::build_in("i32");
107 pub const I64: Self = Self::build_in("i64");
108 pub const I128: Self = Self::build_in("i128");
109 pub const ISIZE: Self = Self::build_in("isize");
110
111 pub const F32: Self = Self::build_in("f32");
112 pub const F64: Self = Self::build_in("f64");
113
114 pub const BOOL: Self = Self::build_in("bool");
115 pub const STR: Self = Self::build_in("str");
116 pub const STRING: Self = Self::build_in("String");
117
118 pub const ANY_TYPE: Self = Self::type_("anyType");
119
120 pub const BUILD_IN: &[Self] = &[
121 Self::U8,
122 Self::U16,
123 Self::U32,
124 Self::U64,
125 Self::U128,
126 Self::USIZE,
127 Self::I8,
128 Self::I16,
129 Self::I32,
130 Self::I64,
131 Self::I128,
132 Self::ISIZE,
133 Self::F32,
134 Self::F64,
135 Self::BOOL,
136 Self::STR,
137 Self::STRING,
138 ];
139}
140
141impl TypeIdent {
142 #[must_use]
144 pub const fn new(name: Name) -> Self {
145 Self {
146 ns: NamespaceId::UNKNOWN,
147 schema: SchemaId::UNKNOWN,
148 name,
149 type_: IdentType::Type,
150 }
151 }
152
153 #[must_use]
155 pub const fn type_(name: &'static str) -> Self {
156 Self {
157 ns: NamespaceId::UNKNOWN,
158 schema: SchemaId::UNKNOWN,
159 name: Name::named(name),
160 type_: IdentType::Type,
161 }
162 }
163
164 #[must_use]
166 pub const fn build_in(name: &'static str) -> Self {
167 Self {
168 ns: NamespaceId::ANONYMOUS,
169 schema: SchemaId::UNKNOWN,
170 name: Name::named(name),
171 type_: IdentType::BuildIn,
172 }
173 }
174
175 #[must_use]
177 pub const fn element(name: &'static str) -> Self {
178 Self {
179 ns: NamespaceId::UNKNOWN,
180 schema: SchemaId::UNKNOWN,
181 name: Name::named(name),
182 type_: IdentType::Element,
183 }
184 }
185
186 #[must_use]
188 pub fn with_ns(mut self, ns: NamespaceId) -> Self {
189 self.ns = ns;
190
191 self
192 }
193
194 #[must_use]
196 pub fn with_schema(mut self, schema: SchemaId) -> Self {
197 self.schema = schema;
198
199 self
200 }
201
202 #[must_use]
204 pub fn with_name(mut self, name: Name) -> Self {
205 self.name = name;
206
207 self
208 }
209
210 #[must_use]
212 pub fn with_type(mut self, type_: TypeIdentType) -> Self {
213 self.type_ = type_;
214
215 self
216 }
217
218 #[must_use]
223 pub fn matches(&self, other: &Self) -> bool {
224 let Self {
225 ns,
226 schema,
227 name,
228 type_,
229 } = self;
230
231 (ns.is_unknown() || other.ns.is_unknown() || ns.eq(&other.ns))
232 && (schema.is_unknown() || other.schema.is_unknown() || schema.eq(&other.schema))
233 && name.eq(&other.name)
234 && type_.eq(&other.type_)
235 }
236
237 #[must_use]
240 pub fn to_property_ident(&self) -> PropertyIdent {
241 let Self {
242 ns,
243 schema: _,
244 name,
245 type_: _,
246 } = self;
247
248 PropertyIdent {
249 ns: *ns,
250 name: name.clone(),
251 }
252 }
253
254 #[must_use]
256 pub fn is_build_in(&self) -> bool {
257 TypeIdent::BUILD_IN.contains(self)
258 }
259
260 #[must_use]
265 pub fn is_fully_qualified(&self) -> bool {
266 !self.ns.is_unknown() && !self.schema.is_unknown()
267 }
268}
269
270impl Display for TypeIdent {
271 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
272 fmt_ident(
273 f,
274 Some(self.ns),
275 Some(self.schema),
276 &self.name,
277 Some(self.type_),
278 )
279 }
280}
281
282impl PropertyIdent {
285 #[inline]
287 #[must_use]
288 pub const fn new(name: Name) -> Self {
289 Self {
290 ns: NamespaceId::UNKNOWN,
291 name,
292 }
293 }
294
295 #[inline]
297 #[must_use]
298 pub const fn named(name: &'static str) -> Self {
299 Self {
300 ns: NamespaceId::UNKNOWN,
301 name: Name::named(name),
302 }
303 }
304
305 #[inline]
307 #[must_use]
308 pub fn with_ns(mut self, ns: NamespaceId) -> Self {
309 self.ns = ns;
310
311 self
312 }
313}
314
315impl Display for PropertyIdent {
316 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
317 fmt_ident(f, Some(self.ns), None, &self.name, None)
318 }
319}
320
321fn fmt_ident(
322 f: &mut Formatter<'_>,
323 ns: Option<NamespaceId>,
324 schema: Option<SchemaId>,
325 name: &Name,
326 type_: Option<IdentType>,
327) -> FmtResult {
328 match type_ {
329 None => write!(f, "Ident(")?,
330 Some(IdentType::Type) => write!(f, "Type(")?,
331 Some(IdentType::Group) => write!(f, "Group(")?,
332 Some(IdentType::BuildIn) => write!(f, "BuildIn(")?,
333 Some(IdentType::Element) => write!(f, "Element(")?,
334 Some(IdentType::ElementType) => write!(f, "ElementType(")?,
335 Some(IdentType::Attribute) => write!(f, "Attribute(")?,
336 Some(IdentType::AttributeGroup) => write!(f, "AttributeGroup(")?,
337 Some(IdentType::Enumeration) => write!(f, "Enumeration(")?,
338 Some(IdentType::NillableContent) => write!(f, "NillableContent(")?,
339 Some(IdentType::DynamicElement) => write!(f, "DynamicElement(")?,
340 }
341
342 if f.sign_minus() {
343 write!(f, "{name})")?;
344 } else {
345 if let Some(SchemaId(schema)) = schema {
346 write!(f, "schema={schema}, ")?;
347 }
348
349 if let Some(ns) = ns {
350 write!(f, "ns={}, name={name})", ns.0)?;
351 } else {
352 write!(f, "ns=default, name={name})")?;
353 }
354 }
355
356 Ok(())
357}