sophia_api/term/
_native_literal.rs1use super::*;
2use crate::ns::xsd;
3
4lazy_static::lazy_static! {
5 static ref XSD_DOUBLE: Box<str> = xsd::double.iri().unwrap().unwrap().into();
6 static ref XSD_INTEGER: Box<str> = xsd::integer.iri().unwrap().unwrap().into();
7 static ref XSD_STRING: Box<str> = xsd::string.iri().unwrap().unwrap().into();
8}
9
10impl Term for f64 {
27 type BorrowTerm<'x> = Self;
28
29 fn kind(&self) -> TermKind {
30 TermKind::Literal
31 }
32 fn lexical_form(&self) -> Option<MownStr> {
33 Some(MownStr::from(format!("{}", self)))
34 }
35 fn datatype(&self) -> Option<IriRef<MownStr>> {
36 Some(IriRef::new_unchecked(MownStr::from_str(&XSD_DOUBLE)))
37 }
38 fn language_tag(&self) -> Option<LanguageTag<MownStr>> {
39 None
40 }
41 fn borrow_term(&self) -> Self::BorrowTerm<'_> {
42 *self
43 }
44}
45
46impl Term for i32 {
63 type BorrowTerm<'x> = Self;
64
65 fn kind(&self) -> TermKind {
66 TermKind::Literal
67 }
68 fn lexical_form(&self) -> Option<MownStr> {
69 Some(MownStr::from(format!("{}", self)))
70 }
71 fn datatype(&self) -> Option<IriRef<MownStr>> {
72 Some(IriRef::new_unchecked(MownStr::from_str(&XSD_INTEGER)))
73 }
74 fn language_tag(&self) -> Option<LanguageTag<MownStr>> {
75 None
76 }
77 fn borrow_term(&self) -> Self::BorrowTerm<'_> {
78 *self
79 }
80}
81
82impl Term for isize {
100 type BorrowTerm<'x> = Self;
101
102 fn kind(&self) -> TermKind {
103 TermKind::Literal
104 }
105 fn lexical_form(&self) -> Option<MownStr> {
106 Some(MownStr::from(format!("{}", self)))
107 }
108 fn datatype(&self) -> Option<IriRef<MownStr>> {
109 Some(IriRef::new_unchecked(MownStr::from_str(&XSD_INTEGER)))
110 }
111 fn language_tag(&self) -> Option<LanguageTag<MownStr>> {
112 None
113 }
114 fn borrow_term(&self) -> Self::BorrowTerm<'_> {
115 *self
116 }
117}
118
119impl Term for usize {
137 type BorrowTerm<'x> = Self;
138
139 fn kind(&self) -> TermKind {
140 TermKind::Literal
141 }
142 fn lexical_form(&self) -> Option<MownStr> {
143 Some(MownStr::from(format!("{}", self)))
144 }
145 fn datatype(&self) -> Option<IriRef<MownStr>> {
146 Some(IriRef::new_unchecked(MownStr::from_str(&XSD_INTEGER)))
147 }
148 fn language_tag(&self) -> Option<LanguageTag<MownStr>> {
149 None
150 }
151 fn borrow_term(&self) -> Self::BorrowTerm<'_> {
152 *self
153 }
154}
155
156impl Term for str {
173 type BorrowTerm<'x> = &'x Self where Self: 'x;
174
175 fn kind(&self) -> TermKind {
176 TermKind::Literal
177 }
178 fn lexical_form(&self) -> Option<MownStr> {
179 Some(MownStr::from(self))
180 }
181 fn datatype(&self) -> Option<IriRef<MownStr>> {
182 Some(IriRef::new_unchecked(MownStr::from_str(&XSD_STRING)))
183 }
184 fn language_tag(&self) -> Option<LanguageTag<MownStr>> {
185 None
186 }
187 fn borrow_term(&self) -> Self::BorrowTerm<'_> {
188 self
189 }
190}
191
192impl TryFromTerm for f64 {
195 type Error = std::num::ParseFloatError;
196
197 fn try_from_term<T: Term>(term: T) -> Result<Self, Self::Error> {
198 if let Some(lex) = term.lexical_form() {
199 if Term::eq(&term.datatype().unwrap(), xsd::double)
200 || Term::eq(&term.datatype().unwrap(), xsd::float)
201 {
202 lex.parse()
203 } else {
204 "wrong datatype".parse()
205 }
206 } else {
207 "not a literal".parse()
208 }
209 }
210}
211
212impl TryFromTerm for i32 {
215 type Error = std::num::ParseIntError;
216
217 fn try_from_term<T: Term>(term: T) -> Result<Self, Self::Error> {
218 if let Some(lex) = term.lexical_form() {
219 if Term::eq(&term.datatype().unwrap(), xsd::integer)
220 || Term::eq(&term.datatype().unwrap(), xsd::long)
221 || Term::eq(&term.datatype().unwrap(), xsd::int)
222 || Term::eq(&term.datatype().unwrap(), xsd::short)
223 || Term::eq(&term.datatype().unwrap(), xsd::unsignedLong)
224 || Term::eq(&term.datatype().unwrap(), xsd::unsignedInt)
225 || Term::eq(&term.datatype().unwrap(), xsd::unsignedShort)
226 || Term::eq(&term.datatype().unwrap(), xsd::unsignedByte)
227 || Term::eq(&term.datatype().unwrap(), xsd::nonNegativeInteger)
228 || Term::eq(&term.datatype().unwrap(), xsd::nonPositiveInteger)
229 {
230 lex.parse()
231 } else {
232 "wrong datatype".parse()
233 }
234 } else {
235 "not a literal".parse()
236 }
237 }
238}
239
240impl TryFromTerm for isize {
243 type Error = std::num::ParseIntError;
244
245 fn try_from_term<T: Term>(term: T) -> Result<Self, Self::Error> {
246 if let Some(lex) = term.lexical_form() {
247 if Term::eq(&term.datatype().unwrap(), xsd::integer)
248 || Term::eq(&term.datatype().unwrap(), xsd::long)
249 || Term::eq(&term.datatype().unwrap(), xsd::int)
250 || Term::eq(&term.datatype().unwrap(), xsd::short)
251 || Term::eq(&term.datatype().unwrap(), xsd::unsignedLong)
252 || Term::eq(&term.datatype().unwrap(), xsd::unsignedInt)
253 || Term::eq(&term.datatype().unwrap(), xsd::unsignedShort)
254 || Term::eq(&term.datatype().unwrap(), xsd::unsignedByte)
255 || Term::eq(&term.datatype().unwrap(), xsd::nonNegativeInteger)
256 || Term::eq(&term.datatype().unwrap(), xsd::nonPositiveInteger)
257 {
258 lex.parse()
259 } else {
260 "wrong datatype".parse()
261 }
262 } else {
263 "not a literal".parse()
264 }
265 }
266}
267
268impl TryFromTerm for usize {
271 type Error = std::num::ParseIntError;
272
273 fn try_from_term<T: Term>(term: T) -> Result<Self, Self::Error> {
274 if let Some(lex) = term.lexical_form() {
275 if Term::eq(&term.datatype().unwrap(), xsd::integer)
276 || Term::eq(&term.datatype().unwrap(), xsd::long)
277 || Term::eq(&term.datatype().unwrap(), xsd::int)
278 || Term::eq(&term.datatype().unwrap(), xsd::short)
279 || Term::eq(&term.datatype().unwrap(), xsd::unsignedLong)
280 || Term::eq(&term.datatype().unwrap(), xsd::unsignedInt)
281 || Term::eq(&term.datatype().unwrap(), xsd::unsignedShort)
282 || Term::eq(&term.datatype().unwrap(), xsd::unsignedByte)
283 || Term::eq(&term.datatype().unwrap(), xsd::nonNegativeInteger)
284 || Term::eq(&term.datatype().unwrap(), xsd::nonPositiveInteger)
285 {
286 lex.parse()
287 } else {
288 "wrong datatype".parse()
289 }
290 } else {
291 "not a literal".parse()
292 }
293 }
294}
295
296#[cfg(test)]
297mod test {
298 use super::*;
299
300 #[test]
301 fn i32_as_literal() {
302 let lit = 42;
303 assert_consistent_term_impl::<i32>(&lit);
304 assert_eq!(lit.kind(), TermKind::Literal);
305 assert_eq!(lit.lexical_form().unwrap(), "42");
306 assert_eq!(lit.datatype(), xsd::integer.iri());
307 assert_eq!(lit.borrow_term(), lit);
308 }
309
310 #[test]
311 fn isize_as_literal() {
312 let lit = 42;
313 assert_consistent_term_impl::<isize>(&lit);
314 assert_eq!(lit.kind(), TermKind::Literal);
315 assert_eq!(lit.lexical_form().unwrap(), "42");
316 assert_eq!(lit.datatype(), xsd::integer.iri());
317 assert_eq!(lit.borrow_term(), lit);
318 }
319
320 #[test]
321 fn usize_as_literal() {
322 let lit = 42;
323 assert_consistent_term_impl::<usize>(&lit);
324 assert_eq!(lit.kind(), TermKind::Literal);
325 assert_eq!(lit.lexical_form().unwrap(), "42");
326 assert_eq!(lit.datatype(), xsd::integer.iri());
327 assert_eq!(lit.borrow_term(), lit);
328 }
329
330 #[test]
331 fn f64_as_literal() {
332 #[allow(clippy::approx_constant)]
333 let lit = 3.14;
334 assert_consistent_term_impl::<f64>(&lit);
335 assert_eq!(lit.kind(), TermKind::Literal);
336 assert_eq!(lit.lexical_form().unwrap(), "3.14");
337 assert_eq!(lit.datatype(), xsd::double.iri());
338 assert_eq!(lit.borrow_term(), lit);
339 }
340
341 #[test]
342 fn str_as_literal() {
343 let lit = "hello world";
344 assert_consistent_term_impl::<&str>(&lit);
345 assert_eq!(lit.kind(), TermKind::Literal);
346 assert_eq!(lit.lexical_form().unwrap(), lit);
347 assert_eq!(lit.datatype(), xsd::string.iri());
348 assert_eq!(lit.borrow_term(), lit);
349 }
350
351 #[test]
352 fn iri_to_native() {
353 assert!(f64::try_from_term(xsd::ID).is_err());
354 assert!(i32::try_from_term(xsd::ID).is_err());
355 assert!(isize::try_from_term(xsd::ID).is_err());
356 assert!(usize::try_from_term(xsd::ID).is_err());
357 }
358
359 #[test]
360 fn wrong_datatype_to_native() {
361 assert!(f64::try_from_term("foo").is_err());
362 assert!(i32::try_from_term("foo").is_err());
363 assert!(isize::try_from_term("foo").is_err());
364 assert!(usize::try_from_term("foo").is_err());
365 }
366
367 #[test]
368 fn correct_datatype_to_native() {
369 assert_eq!(f64::try_from_term(3.15).unwrap(), 3.15);
370 assert_eq!(i32::try_from_term(42).unwrap(), 42);
371 assert_eq!(isize::try_from_term(42).unwrap(), 42);
372 assert_eq!(usize::try_from_term(42).unwrap(), 42);
373 }
374}