1use crate::{DecimalType, DecimalValue, PrimitiveType, PrimitiveValue};
4use core::{fmt, str::FromStr};
5use phf::phf_map;
6
7#[cfg(feature = "alloc")]
8use ::alloc::{borrow::Cow, format, string::String, vec::Vec};
9
10#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
20#[cfg_attr(
21 feature = "borsh",
22 derive(borsh::BorshSerialize, borsh::BorshDeserialize)
23)]
24#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
25pub enum Type {
26 Primitive(PrimitiveType),
27
28 Decimal(DecimalType),
29
30 #[cfg(feature = "alloc")]
31 Other(String),
32 #[cfg(not(feature = "alloc"))]
33 Other(&'static str),
34}
35
36impl Type {
37 pub fn name(&self) -> &str {
38 use Type::*;
39 match self {
40 Decimal(t) => t.name(),
41 Primitive(t) => t.name(),
42 Other(s) => s.as_ref(),
43 }
44 }
45
46 pub fn curie(&self) -> &str {
47 use Type::*;
48 match self {
49 Decimal(t) => t.curie(),
50 Primitive(t) => t.curie(),
51 Other(s) => s.as_ref(), }
53 }
54
55 #[cfg(feature = "alloc")]
61 pub fn iri_string(&self) -> Cow<'_, str> {
62 let name = self.name();
63 if name.contains(':') {
64 Cow::Borrowed(name)
65 } else {
66 Cow::Owned(format!("{}{}", crate::BASE_URI, name))
67 }
68 }
69
70 pub fn base_type(&self) -> Option<Type> {
71 use Type::*;
72 match self {
73 Decimal(t) => t.base_type().map(Decimal),
74 Primitive(_) => None,
75 Other(_) => None,
76 }
77 }
78
79 #[cfg(feature = "alloc")]
80 pub fn base_types(&self) -> Vec<Type> {
81 use Type::*;
82 match self {
83 Decimal(t) => t.base_types().into_iter().map(Decimal).collect(),
84 Primitive(_) => Vec::new(),
85 Other(_) => Vec::new(),
86 }
87 }
88}
89
90impl fmt::Display for Type {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 f.write_str(self.name())
93 }
94}
95
96impl FromStr for Type {
97 type Err = (); fn from_str(input: &str) -> Result<Self, Self::Err> {
100 match TYPES.get(input) {
101 Some(&t) => Ok(t.clone()),
102 None => Err(()),
103 }
104 }
105}
106
107impl From<&Type> for Type {
108 fn from(input: &Type) -> Self {
109 input.clone()
110 }
111}
112
113#[cfg(all(feature = "oxrdf", feature = "alloc"))]
114impl From<oxrdf::NamedNode> for Type {
115 fn from(input: oxrdf::NamedNode) -> Self {
116 let input_iri = input.as_str();
117 if let Some(input_name) = input_iri.strip_prefix(crate::BASE_URI) {
118 return Type::from(input_name);
119 }
120 Type::Other(input_iri.into()) }
122}
123
124#[cfg(feature = "alloc")]
125impl From<&str> for Type {
126 fn from(input: &str) -> Self {
127 match TYPES.get(input) {
128 Some(&t) => t.clone(),
129 None => Type::Other(input.into()),
130 }
131 }
132}
133
134#[cfg(not(feature = "alloc"))]
135impl From<&'static str> for Type {
136 fn from(input: &'static str) -> Self {
137 match TYPES.get(input) {
138 Some(&t) => t.clone(),
139 None => Type::Other(input.into()),
140 }
141 }
142}
143
144impl From<DecimalType> for Type {
145 fn from(input: DecimalType) -> Self {
146 Self::Decimal(input)
147 }
148}
149
150impl From<DecimalValue> for Type {
151 fn from(input: DecimalValue) -> Self {
152 Self::Decimal(input.r#type())
153 }
154}
155
156impl From<PrimitiveType> for Type {
157 fn from(input: PrimitiveType) -> Self {
158 Self::Primitive(input)
159 }
160}
161
162impl From<PrimitiveValue> for Type {
163 fn from(input: PrimitiveValue) -> Self {
164 Self::Primitive(input.r#type())
165 }
166}
167
168pub static TYPES: phf::Map<&'static str, &'static Type> = phf_map! {
170 "QName" => &QNAME,
171 "anyURI" => &ANY_URI,
172 "base64Binary" => &BASE64_BINARY,
173 "boolean" => &BOOLEAN,
174 "byte" => &BYTE,
175 "date" => &DATE,
176 "dateTime" => &DATE_TIME,
177 "decimal" => &DECIMAL,
178 "double" => &DOUBLE,
179 "duration" => &DURATION,
180 "float" => &FLOAT,
181 "gDay" => &G_DAY,
182 "gMonth" => &G_MONTH,
183 "gMonthDay" => &G_MONTH_DAY,
184 "gYear" => &G_YEAR,
185 "gYearMonth" => &G_YEAR_MONTH,
186 "hexBinary" => &HEX_BINARY,
187 "int" => &INT,
188 "integer" => &INTEGER,
189 "long" => &LONG,
190 "short" => &SHORT,
191 "string" => &STRING,
192 "time" => &TIME,
193};
194
195pub const QNAME: Type = Type::Primitive(PrimitiveType::QName);
197
198pub const ANY_URI: Type = Type::Primitive(PrimitiveType::AnyUri);
200
201pub const BASE64_BINARY: Type = Type::Primitive(PrimitiveType::Base64Binary);
203
204pub const BOOLEAN: Type = Type::Primitive(PrimitiveType::Boolean);
206
207pub const BYTE: Type = Type::Decimal(DecimalType::Byte);
209
210pub const DATE: Type = Type::Primitive(PrimitiveType::Date);
212
213pub const DATE_TIME: Type = Type::Primitive(PrimitiveType::DateTime);
215
216pub const DECIMAL: Type = Type::Decimal(DecimalType::Decimal);
218
219pub const DOUBLE: Type = Type::Primitive(PrimitiveType::Double);
221
222pub const DURATION: Type = Type::Primitive(PrimitiveType::Duration);
224
225pub const FLOAT: Type = Type::Primitive(PrimitiveType::Float);
227
228pub const G_DAY: Type = Type::Primitive(PrimitiveType::GDay);
230
231pub const G_MONTH: Type = Type::Primitive(PrimitiveType::GMonth);
233
234pub const G_MONTH_DAY: Type = Type::Primitive(PrimitiveType::GMonthDay);
236
237pub const G_YEAR: Type = Type::Primitive(PrimitiveType::GYear);
239
240pub const G_YEAR_MONTH: Type = Type::Primitive(PrimitiveType::GYearMonth);
242
243pub const HEX_BINARY: Type = Type::Primitive(PrimitiveType::HexBinary);
245
246pub const INT: Type = Type::Decimal(DecimalType::Int);
248
249pub const INTEGER: Type = Type::Decimal(DecimalType::Integer);
251
252pub const LONG: Type = Type::Decimal(DecimalType::Long);
254
255pub const SHORT: Type = Type::Decimal(DecimalType::Short);
257
258pub const STRING: Type = Type::Primitive(PrimitiveType::String);
260
261pub const TIME: Type = Type::Primitive(PrimitiveType::Time);