1use std::fmt::{Display, Formatter, Result as FmtResult};
4use std::hash::Hash;
5
6use crate::models::schema::NamespaceId;
7
8use super::Name;
9
10#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
12pub struct Ident {
13 pub ns: Option<NamespaceId>,
15
16 pub name: Name,
18
19 pub type_: IdentType,
21}
22
23#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
25pub enum IdentType {
26 Type = 0,
28
29 Group = 1,
31
32 Element = 2,
34
35 ElementType = 3,
37
38 Attribute = 4,
40
41 AttributeGroup = 5,
43
44 BuildIn = 6,
46
47 Enumeration = 7,
49
50 NillableContent = 8,
52
53 DynamicElement = 9,
55}
56
57#[allow(missing_docs)]
58impl Ident {
59 pub const UNKNOWN: Self = Self::type_("UNKNOWN");
60
61 pub const U8: Self = Self::build_in("u8");
62 pub const U16: Self = Self::build_in("u16");
63 pub const U32: Self = Self::build_in("u32");
64 pub const U64: Self = Self::build_in("u64");
65 pub const U128: Self = Self::build_in("u128");
66 pub const USIZE: Self = Self::build_in("usize");
67
68 pub const I8: Self = Self::build_in("i8");
69 pub const I16: Self = Self::build_in("i16");
70 pub const I32: Self = Self::build_in("i32");
71 pub const I64: Self = Self::build_in("i64");
72 pub const I128: Self = Self::build_in("i128");
73 pub const ISIZE: Self = Self::build_in("isize");
74
75 pub const F32: Self = Self::build_in("f32");
76 pub const F64: Self = Self::build_in("f64");
77
78 pub const BOOL: Self = Self::build_in("bool");
79 pub const STRING: Self = Self::build_in("String");
80
81 pub const ANY_TYPE: Self = Self::type_("anyType");
82
83 pub const BUILD_IN: &[Self] = &[
84 Self::U8,
85 Self::U16,
86 Self::U32,
87 Self::U64,
88 Self::U128,
89 Self::USIZE,
90 Self::I8,
91 Self::I16,
92 Self::I32,
93 Self::I64,
94 Self::I128,
95 Self::ISIZE,
96 Self::F32,
97 Self::F64,
98 Self::BOOL,
99 Self::STRING,
100 ];
101}
102
103impl Ident {
104 #[must_use]
106 pub fn new(name: Name) -> Self {
107 Self {
108 ns: None,
109 name,
110 type_: IdentType::Type,
111 }
112 }
113
114 #[must_use]
116 pub const fn type_(name: &'static str) -> Self {
117 Self {
118 ns: None,
119 name: Name::named(name),
120 type_: IdentType::Type,
121 }
122 }
123
124 #[must_use]
126 pub const fn build_in(name: &'static str) -> Self {
127 Self {
128 ns: None,
129 name: Name::named(name),
130 type_: IdentType::BuildIn,
131 }
132 }
133
134 #[must_use]
136 pub const fn element(name: &'static str) -> Self {
137 Self {
138 ns: None,
139 name: Name::named(name),
140 type_: IdentType::Element,
141 }
142 }
143
144 #[must_use]
146 pub const fn name(name: &'static str) -> Self {
147 Self::type_(name)
149 }
150
151 #[must_use]
153 pub fn with_ns(mut self, ns: Option<NamespaceId>) -> Self {
154 self.ns = ns;
155
156 self
157 }
158
159 #[must_use]
161 pub fn with_type(mut self, type_: IdentType) -> Self {
162 self.type_ = type_;
163
164 self
165 }
166
167 #[must_use]
169 pub fn is_build_in(&self) -> bool {
170 Ident::BUILD_IN.contains(self)
171 }
172}
173
174impl Display for Ident {
175 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
176 let Self { ns, name, type_ } = self;
177
178 match type_ {
179 IdentType::Type => write!(f, "Type(")?,
180 IdentType::Group => write!(f, "Group(")?,
181 IdentType::BuildIn => write!(f, "BuildIn(")?,
182 IdentType::Element => write!(f, "Element(")?,
183 IdentType::ElementType => write!(f, "ElementType(")?,
184 IdentType::Attribute => write!(f, "Attribute(")?,
185 IdentType::AttributeGroup => write!(f, "AttributeGroup(")?,
186 IdentType::Enumeration => write!(f, "Enumeration(")?,
187 IdentType::NillableContent => write!(f, "NillableContent(")?,
188 IdentType::DynamicElement => write!(f, "DynamicElement(")?,
189 }
190
191 if f.sign_minus() {
192 write!(f, "{name})")?;
193 } else if let Some(ns) = ns {
194 write!(f, "ns={}, name={name})", ns.0)?;
195 } else {
196 write!(f, "ns=default, name={name})")?;
197 }
198
199 Ok(())
200 }
201}