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