ekg_namespace/
data_type.rs

1#[cfg(feature = "serde")]
2use serde::Serialize;
3use {num_enum::TryFromPrimitive, phf::phf_map};
4
5static DATA_TYPE_MAP: phf::Map<&'static str, DataType> = phf_map! {
6    "Unbound Value" => DataType::UnboundValue,
7    "Blank Node" => DataType::BlankNode,
8    "IRI Reference" => DataType::IriReference,
9    "http://www.w3.org/2000/01/rdf-schema#Literal" => DataType::Literal,
10    "http://www.w3.org/2001/XMLSchema#anyURI" => DataType::AnyUri,
11    "http://www.w3.org/2001/XMLSchema#boolean" => DataType::Boolean,
12    "http://www.w3.org/2001/XMLSchema#byte" => DataType::Byte,
13    "http://www.w3.org/2001/XMLSchema#date" => DataType::Date,
14    "http://www.w3.org/2001/XMLSchema#dateTime" => DataType::DateTime,
15    "http://www.w3.org/2001/XMLSchema#dateTimeStamp" => DataType::DateTimeStamp,
16    "http://www.w3.org/2001/XMLSchema#gDay" => DataType::Day,
17    "http://www.w3.org/2001/XMLSchema#dayTimeDuration" => DataType::DayTimeDuration,
18    "http://www.w3.org/2001/XMLSchema#decimal" => DataType::Decimal,
19    "http://www.w3.org/2001/XMLSchema#double" => DataType::Double,
20    "http://www.w3.org/2001/XMLSchema#duration" => DataType::Duration,
21    "http://www.w3.org/2001/XMLSchema#float" => DataType::Float,
22    "http://www.w3.org/2001/XMLSchema#int" => DataType::Int,
23    "http://www.w3.org/2001/XMLSchema#integer" => DataType::Integer,
24    "http://www.w3.org/2001/XMLSchema#long" => DataType::Long,
25    "http://www.w3.org/2001/XMLSchema#gMonth" => DataType::Month,
26    "http://www.w3.org/2001/XMLSchema#gMonthDay" => DataType::MonthDay,
27    "http://www.w3.org/2001/XMLSchema#negativeInteger" => DataType::NegativeInteger,
28    "http://www.w3.org/2001/XMLSchema#nonNegativeInteger" => DataType::NonNegativeInteger,
29    "http://www.w3.org/2001/XMLSchema#nonPositiveInteger" => DataType::NonPositiveInteger,
30    "http://www.w3.org/2001/XMLSchema#short" => DataType::Short,
31    "http://www.w3.org/2001/XMLSchema#string" => DataType::String,
32    "http://www.w3.org/2001/XMLSchema#time" => DataType::Time,
33    "http://www.w3.org/2001/XMLSchema#unsignedByte" => DataType::UnsignedByte,
34    "http://www.w3.org/2001/XMLSchema#unsignedInt" => DataType::UnsignedInt,
35    "http://www.w3.org/2001/XMLSchema#unsignedLong" => DataType::UnsignedLong,
36    "http://www.w3.org/2001/XMLSchema#unsignedShort" => DataType::UnsignedShort,
37    "http://www.w3.org/2001/XMLSchema#gYear" => DataType::Year,
38    "http://www.w3.org/2001/XMLSchema#gYearMonth" => DataType::YearMonth,
39    "http://www.w3.org/2001/XMLSchema#yearMonthDuration" => DataType::YearMonthDuration,
40};
41
42/// The XSD DataType of a given [`Literal`](crate::Literal).
43///
44/// See also <https://docs.oxfordsemantic.tech/_javadoc/tech/oxfordsemantic/jrdfox/logic/Datatype.html>.
45#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone, TryFromPrimitive)]
46#[cfg_attr(feature = "serde", derive(Serialize))]
47#[repr(u8)]
48pub enum DataType {
49    /// INVALID_DATATYPE
50    UnboundValue       = 0,
51    /// BLANK_NODE
52    BlankNode          = 1,
53    /// IRI_REFERENCE
54    IriReference       = 2,
55    /// RDFS_LITERAL
56    Literal            = 3,
57    /// XSD_ANY_URI
58    AnyUri             = 4,
59    /// XSD_STRING
60    String             = 5,
61    /// RDF_PLAIN_LITERAL
62    PlainLiteral       = 6,
63    /// XSD_BOOLEAN
64    Boolean            = 7,
65    /// XSD_DATE_TIME
66    DateTime           = 8,
67    /// XSD_DATE_TIME_STAMP
68    DateTimeStamp      = 9,
69    /// XSD_TIME
70    Time               = 10,
71    /// XSD_DATE
72    Date               = 11,
73    /// XSD_G_YEAR_MONTH
74    YearMonth          = 12,
75    /// XSD_G_YEAR
76    Year               = 13,
77    /// XSD_G_MONTH_DAY
78    MonthDay           = 14,
79    /// XSD_G_DAY
80    Day                = 15,
81    /// XSD_G_MONTH
82    Month              = 16,
83    /// XSD_DURATION
84    Duration           = 17,
85    /// XSD_YEAR_MONTH_DURATION
86    YearMonthDuration  = 18,
87    /// XSD_DAY_TIME_DURATION
88    DayTimeDuration    = 19,
89    /// XSD_DOUBLE
90    Double             = 20,
91    /// XSD_FLOAT
92    Float              = 21,
93    /// XSD_DECIMAL
94    Decimal            = 22,
95    /// XSD_INTEGER
96    Integer            = 23,
97    /// XSD_NON_NEGATIVE_INTEGER
98    NonNegativeInteger = 24,
99    /// XSD_NON_POSITIVE_INTEGER
100    NonPositiveInteger = 25,
101    /// XSD_NEGATIVE_INTEGER
102    NegativeInteger    = 26,
103    /// XSD_POSITIVE_INTEGER
104    PositiveInteger    = 27,
105    /// XSD_LONG
106    Long               = 28,
107    /// XSD_INT
108    Int                = 29,
109    /// XSD_SHORT
110    Short              = 30,
111    /// XSD_BYTE
112    Byte               = 31,
113    /// XSD_UNSIGNED_LONG
114    UnsignedLong       = 32,
115    /// XSD_UNSIGNED_INT
116    UnsignedInt        = 33,
117    /// XSD_UNSIGNED_SHORT
118    UnsignedShort      = 34,
119    /// XSD_UNSIGNED_BYTE
120    UnsignedByte       = 35,
121}
122
123impl Default for DataType {
124    /// Choosing boolean here as the default type because the default
125    /// for `LexicalValueUnion` is a boolean false.
126    fn default() -> Self { DataType::Boolean }
127}
128
129impl DataType {
130    pub fn from_datatype_id(data_type_id: u8) -> Result<DataType, ekg_error::Error> {
131        DataType::try_from(data_type_id)
132            .map_err(|_err| ekg_error::Error::UnknownDataType { data_type_id })
133    }
134
135    pub fn from_xsd_iri(iri: &str) -> Result<Self, ekg_error::Error> {
136        if let Some(data_type) = DATA_TYPE_MAP.get(iri) {
137            Ok(*data_type)
138        } else {
139            Err(ekg_error::Error::UnknownXsdDataType { data_type_iri: iri.to_string() })
140        }
141    }
142
143    pub fn as_xsd_iri_str(&self) -> &'static str {
144        DATA_TYPE_MAP
145            .entries()
146            .find_map(
147                |(key, val)| {
148                    if val == self { Some(key) } else { None }
149                },
150            )
151            .unwrap_or_else(|| panic!("You've managed to create an unknown DataType instance"))
152    }
153
154    #[inline]
155    pub fn is_string(&self) -> bool { matches!(self, DataType::String | DataType::PlainLiteral) }
156
157    #[inline]
158    pub fn is_iri(&self) -> bool { matches!(self, DataType::AnyUri | DataType::IriReference) }
159
160    #[inline]
161    pub fn is_boolean(&self) -> bool { matches!(self, DataType::Boolean) }
162
163    #[inline]
164    pub fn is_date(&self) -> bool { matches!(self, DataType::Date) }
165
166    #[inline]
167    pub fn is_date_time(&self) -> bool { matches!(self, DataType::DateTime) }
168
169    #[inline]
170    pub fn is_decimal(&self) -> bool { matches!(self, DataType::Decimal) }
171
172    #[inline]
173    pub fn is_date_time_stamp(&self) -> bool { matches!(self, DataType::DateTimeStamp) }
174
175    #[inline]
176    pub fn is_duration(&self) -> bool { matches!(self, DataType::Duration) }
177
178    #[inline]
179    pub fn is_signed_integer(&self) -> bool {
180        // IRI_TYPES
181        matches!(
182            self,
183            DataType::Int |
184                DataType::Integer |
185                DataType::NegativeInteger |
186                DataType::NonPositiveInteger |
187                DataType::Long |
188                DataType::Short
189        )
190    }
191
192    #[inline]
193    pub fn is_unsigned_integer(&self) -> bool {
194        // IRI_TYPES
195        matches!(
196            self,
197            DataType::PositiveInteger |
198                DataType::NonNegativeInteger |
199                DataType::UnsignedByte |
200                DataType::UnsignedInt |
201                DataType::UnsignedShort |
202                DataType::UnsignedLong
203        )
204    }
205
206    #[inline]
207    pub fn is_integer(&self) -> bool { self.is_unsigned_integer() || self.is_signed_integer() }
208
209    #[inline]
210    pub fn is_blank_node(&self) -> bool {
211        // BLANK_NODE_TYPES
212        matches!(self, DataType::BlankNode)
213    }
214}