1use rio_api::model::{Quad as RioQuad, Term as RioTerm, Triple as RioTriple, *};
12use sophia_api::ns::{rdf, xsd};
13use sophia_api::quad::{QBorrowTerm, Quad, Spog};
14use sophia_api::term::{BnodeId, LanguageTag, Term, TermKind, VarName};
15use sophia_api::triple::{TBorrowTerm, Triple};
16use sophia_api::MownStr;
17use sophia_iri::{Iri, IriRef};
18
19impl<'a> Term for Trusted<BlankNode<'a>> {
20 type BorrowTerm<'x> = Self where Self: 'x;
21
22 fn kind(&self) -> TermKind {
23 TermKind::BlankNode
24 }
25
26 fn bnode_id(&self) -> Option<BnodeId<MownStr>> {
27 Some(bnode_id(self.0))
28 }
29
30 fn borrow_term(&self) -> Self::BorrowTerm<'_> {
31 *self
32 }
33}
34
35fn bnode_id(b: BlankNode) -> BnodeId<MownStr> {
36 debug_assert!(BnodeId::new(b.id).is_ok());
37 BnodeId::new_unchecked(b.id.into())
38}
39
40impl<'a> Term for Trusted<NamedNode<'a>> {
41 type BorrowTerm<'x> = Self where Self: 'x;
42
43 fn kind(&self) -> TermKind {
44 TermKind::Iri
45 }
46
47 fn iri(&self) -> Option<sophia_iri::IriRef<MownStr<'_>>> {
48 Some(iri(self.0))
49 }
50
51 fn borrow_term(&self) -> Self::BorrowTerm<'_> {
52 *self
53 }
54}
55
56fn iri(n: NamedNode) -> IriRef<MownStr> {
57 debug_assert!(IriRef::new(n.iri).is_ok());
58 IriRef::new_unchecked(n.iri.into())
59}
60
61impl<'a> Term for Trusted<Variable<'a>> {
62 type BorrowTerm<'x> = Self where Self: 'x;
63
64 fn kind(&self) -> TermKind {
65 TermKind::Variable
66 }
67
68 fn variable(&self) -> Option<VarName<MownStr>> {
69 Some(variable(self.0))
70 }
71
72 fn borrow_term(&self) -> Self::BorrowTerm<'_> {
73 *self
74 }
75}
76
77fn variable(v: Variable) -> VarName<MownStr> {
78 debug_assert!(VarName::new(v.name).is_ok());
79 VarName::new_unchecked(v.name.into())
80}
81
82impl<'a> Term for Trusted<Literal<'a>> {
83 type BorrowTerm<'x> = Self where Self: 'x;
84
85 fn kind(&self) -> TermKind {
86 TermKind::Literal
87 }
88
89 fn lexical_form(&self) -> Option<MownStr> {
90 Some(lexical_form(self.0))
91 }
92
93 fn datatype(&self) -> Option<IriRef<MownStr>> {
94 Some(datatype(self.0))
95 }
96
97 fn language_tag(&self) -> Option<LanguageTag<MownStr>> {
98 language_tag(self.0)
99 }
100
101 fn borrow_term(&self) -> Self::BorrowTerm<'_> {
102 *self
103 }
104}
105
106fn lexical_form(l: Literal) -> MownStr {
107 use Literal::*;
108 let value = match l {
109 Simple { value } => value,
110 LanguageTaggedString { value, .. } => value,
111 Typed { value, .. } => value,
112 };
113 value.into()
114}
115
116fn datatype(l: Literal) -> IriRef<MownStr> {
117 use Literal::*;
118 let dt = match l {
119 Simple { .. } => xsd::string.iriref(),
120 LanguageTaggedString { .. } => rdf::langString.iriref(),
121 Typed { datatype, .. } => {
122 debug_assert!(Iri::new(datatype.iri).is_ok());
123 IriRef::new_unchecked(datatype.iri.into())
124 }
125 };
126 dt
127}
128
129fn language_tag(l: Literal) -> Option<LanguageTag<MownStr>> {
130 if let Literal::LanguageTaggedString { language, .. } = l {
131 debug_assert!(LanguageTag::new(language).is_ok());
132 Some(LanguageTag::new_unchecked(language.into()))
133 } else {
134 None
135 }
136}
137
138impl<'a> Term for Trusted<GraphName<'a>> {
206 type BorrowTerm<'x> = Self where Self: 'x;
207
208 fn kind(&self) -> TermKind {
209 use GraphName::*;
210 match self.0 {
211 NamedNode(_) => TermKind::Iri,
212 BlankNode(_) => TermKind::BlankNode,
213 }
214 }
215
216 fn iri(&self) -> Option<IriRef<MownStr<'_>>> {
217 if let GraphName::NamedNode(n) = self.0 {
218 Some(iri(n))
219 } else {
220 None
221 }
222 }
223
224 fn bnode_id(&self) -> Option<BnodeId<MownStr>> {
225 if let GraphName::BlankNode(b) = self.0 {
226 Some(bnode_id(b))
227 } else {
228 None
229 }
230 }
231
232 fn borrow_term(&self) -> Self::BorrowTerm<'_> {
233 Trusted(self.0)
234 }
235}
236
237impl<'a> Term for Trusted<RioTerm<'a>> {
238 type BorrowTerm<'x> = Self where Self: 'x;
239
240 fn kind(&self) -> TermKind {
241 use RioTerm::*;
242 match self.0 {
243 NamedNode(_) => TermKind::Iri,
244 BlankNode(_) => TermKind::BlankNode,
245 Literal(_) => TermKind::Literal,
246 Triple(_) => TermKind::Triple,
247 }
248 }
249
250 fn iri(&self) -> Option<IriRef<MownStr>> {
251 if let RioTerm::NamedNode(n) = self.0 {
252 Some(iri(n))
253 } else {
254 None
255 }
256 }
257
258 fn bnode_id(&self) -> Option<BnodeId<MownStr>> {
259 if let RioTerm::BlankNode(b) = self.0 {
260 Some(bnode_id(b))
261 } else {
262 None
263 }
264 }
265
266 fn lexical_form(&self) -> Option<MownStr> {
267 if let RioTerm::Literal(l) = self.0 {
268 Some(lexical_form(l))
269 } else {
270 None
271 }
272 }
273
274 fn datatype(&self) -> Option<IriRef<MownStr>> {
275 if let RioTerm::Literal(l) = self.0 {
276 Some(datatype(l))
277 } else {
278 None
279 }
280 }
281
282 fn language_tag(&self) -> Option<LanguageTag<MownStr>> {
283 if let RioTerm::Literal(l) = self.0 {
284 language_tag(l)
285 } else {
286 None
287 }
288 }
289
290 fn triple(&self) -> Option<[Self::BorrowTerm<'_>; 3]> {
291 self.to_triple()
292 }
293
294 fn to_triple(self) -> Option<[Self; 3]>
295 where
296 Self: Sized,
297 {
298 if let RioTerm::Triple(t) = self.0 {
299 let s = Trusted(t.subject.into());
300 let p = Trusted(t.predicate.into());
301 let o = Trusted(t.object);
302 Some([s, p, o])
303 } else {
304 None
305 }
306 }
307
308 fn borrow_term(&self) -> Self::BorrowTerm<'_> {
309 *self
310 }
311}
312
313impl<'a> Term for Trusted<GeneralizedTerm<'a>> {
314 type BorrowTerm<'x> = Self where Self: 'x;
315
316 fn kind(&self) -> TermKind {
317 use GeneralizedTerm::*;
318 match self.0 {
319 NamedNode(_) => TermKind::Iri,
320 BlankNode(_) => TermKind::BlankNode,
321 Literal(_) => TermKind::Literal,
322 Triple(_) => TermKind::Triple,
323 Variable(_) => TermKind::Variable,
324 }
325 }
326
327 fn iri(&self) -> Option<IriRef<MownStr>> {
328 if let GeneralizedTerm::NamedNode(n) = self.0 {
329 Some(iri(n))
330 } else {
331 None
332 }
333 }
334
335 fn bnode_id(&self) -> Option<BnodeId<MownStr>> {
336 if let GeneralizedTerm::BlankNode(b) = self.0 {
337 Some(bnode_id(b))
338 } else {
339 None
340 }
341 }
342
343 fn lexical_form(&self) -> Option<MownStr> {
344 if let GeneralizedTerm::Literal(l) = self.0 {
345 Some(lexical_form(l))
346 } else {
347 None
348 }
349 }
350
351 fn datatype(&self) -> Option<IriRef<MownStr>> {
352 if let GeneralizedTerm::Literal(l) = self.0 {
353 Some(datatype(l))
354 } else {
355 None
356 }
357 }
358
359 fn language_tag(&self) -> Option<LanguageTag<MownStr>> {
360 if let GeneralizedTerm::Literal(l) = self.0 {
361 language_tag(l)
362 } else {
363 None
364 }
365 }
366
367 fn triple(&self) -> Option<[Self::BorrowTerm<'_>; 3]> {
368 self.to_triple()
369 }
370
371 fn to_triple(self) -> Option<[Self; 3]>
372 where
373 Self: Sized,
374 {
375 if let GeneralizedTerm::Triple(t) = self.0 {
376 let s = Trusted(t[0]);
377 let p = Trusted(t[1]);
378 let o = Trusted(t[2]);
379 Some([s, p, o])
380 } else {
381 None
382 }
383 }
384
385 fn variable(&self) -> Option<VarName<MownStr>> {
386 if let GeneralizedTerm::Variable(v) = self.0 {
387 Some(variable(v))
388 } else {
389 None
390 }
391 }
392
393 fn borrow_term(&self) -> Self::BorrowTerm<'_> {
394 *self
395 }
396}
397
398impl<'a> Triple for Trusted<RioTriple<'a>> {
399 type Term = Trusted<RioTerm<'a>>;
400
401 fn s(&self) -> TBorrowTerm<Self> {
402 Trusted(self.subject.into())
403 }
404
405 fn p(&self) -> TBorrowTerm<Self> {
406 Trusted(self.predicate.into())
407 }
408
409 fn o(&self) -> TBorrowTerm<Self> {
410 Trusted(self.object)
411 }
412
413 fn to_s(self) -> Self::Term {
414 Trusted(self.subject.into())
415 }
416
417 fn to_p(self) -> Self::Term {
418 Trusted(self.predicate.into())
419 }
420
421 fn to_o(self) -> Self::Term {
422 Trusted(self.object)
423 }
424
425 fn to_spo(self) -> [Self::Term; 3] {
426 [self.to_s(), self.to_p(), self.to_o()]
427 }
428}
429
430impl<'a> Quad for Trusted<RioQuad<'a>> {
431 type Term = Trusted<RioTerm<'a>>;
432
433 fn s(&self) -> QBorrowTerm<Self> {
434 Trusted(self.subject.into())
435 }
436
437 fn p(&self) -> QBorrowTerm<Self> {
438 Trusted(self.predicate.into())
439 }
440
441 fn o(&self) -> QBorrowTerm<Self> {
442 Trusted(self.object)
443 }
444
445 fn g(&self) -> Option<QBorrowTerm<Self>> {
446 self.graph_name.map(|g| Trusted(g.into()))
447 }
448
449 fn to_s(self) -> Self::Term {
450 Trusted(self.subject.into())
451 }
452
453 fn to_p(self) -> Self::Term {
454 Trusted(self.predicate.into())
455 }
456
457 fn to_o(self) -> Self::Term {
458 Trusted(self.object)
459 }
460
461 fn to_g(self) -> Option<Self::Term> {
462 self.graph_name.map(|g| Trusted(g.into()))
463 }
464
465 fn to_spog(self) -> Spog<Self::Term> {
466 ([self.to_s(), self.to_p(), self.to_o()], self.to_g())
467 }
468}
469
470impl<'a> Quad for Trusted<GeneralizedQuad<'a>> {
471 type Term = Trusted<GeneralizedTerm<'a>>;
472
473 fn s(&self) -> QBorrowTerm<Self> {
474 Trusted(self.subject)
475 }
476
477 fn p(&self) -> QBorrowTerm<Self> {
478 Trusted(self.predicate)
479 }
480
481 fn o(&self) -> QBorrowTerm<Self> {
482 Trusted(self.object)
483 }
484
485 fn g(&self) -> Option<QBorrowTerm<Self>> {
486 self.graph_name.map(Trusted)
487 }
488
489 fn to_s(self) -> Self::Term {
490 Trusted(self.subject)
491 }
492
493 fn to_p(self) -> Self::Term {
494 Trusted(self.predicate)
495 }
496
497 fn to_o(self) -> Self::Term {
498 Trusted(self.object)
499 }
500
501 fn to_g(self) -> Option<Self::Term> {
502 self.graph_name.map(Trusted)
503 }
504
505 fn to_spog(self) -> Spog<Self::Term> {
506 ([self.s(), self.p(), self.o()], self.g())
507 }
508}
509
510#[derive(Clone, Copy, Debug)]
512pub struct Trusted<T>(pub T);
513
514impl<T> std::ops::Deref for Trusted<T> {
515 type Target = T;
516
517 fn deref(&self) -> &Self::Target {
518 &self.0
519 }
520}
521
522#[cfg(test)]
523mod test {
524 use super::*;
525 use sophia_api::term::assert_consistent_term_impl;
526
527 #[test]
528 fn blank_node() {
529 assert_consistent_term_impl(&Trusted(BlankNode { id: "foo" }))
530 }
531
532 #[test]
533 fn named_node() {
534 assert_consistent_term_impl(&Trusted(NamedNode { iri: "tag:foo" }));
535 }
536
537 #[test]
538 fn variable() {
539 assert_consistent_term_impl(&Trusted(Variable { name: "foo" }));
540 }
541
542 #[test]
543 fn literal_simple() {
544 assert_consistent_term_impl(&Trusted(Literal::Simple { value: "foo" }));
545 }
546
547 #[test]
548 fn literal_language() {
549 assert_consistent_term_impl(&Trusted(Literal::LanguageTaggedString {
550 value: "foo",
551 language: "en",
552 }));
553 }
554
555 #[test]
556 fn literal_typed() {
557 let datatype = xsd::integer.iriref().to_string();
558 let datatype = NamedNode { iri: &datatype };
559 assert_consistent_term_impl(&Trusted(Literal::Typed {
560 value: "42",
561 datatype,
562 }));
563 }
564
565 #[test]
596 fn graph_name_blank_node() {
597 let t: GraphName = BlankNode { id: "foo" }.into();
598 assert_consistent_term_impl(&Trusted(t))
599 }
600
601 #[test]
602 fn graph_name_named_node() {
603 let t: GraphName = NamedNode { iri: "tag:foo" }.into();
604 assert_consistent_term_impl(&Trusted(t));
605 }
606
607 #[test]
608 fn term_blank_node() {
609 let t: RioTerm = BlankNode { id: "foo" }.into();
610 assert_consistent_term_impl(&Trusted(t))
611 }
612
613 #[test]
614 fn term_named_node() {
615 let t: RioTerm = NamedNode { iri: "tag:foo" }.into();
616 assert_consistent_term_impl(&Trusted(t));
617 }
618
619 #[test]
620 fn term_literal_simple() {
621 let t: RioTerm = Literal::Simple { value: "foo" }.into();
622 assert_consistent_term_impl(&Trusted(t));
623 }
624
625 #[test]
626 fn term_literal_language() {
627 let t: RioTerm = Literal::LanguageTaggedString {
628 value: "foo",
629 language: "en",
630 }
631 .into();
632 assert_consistent_term_impl(&Trusted(t));
633 }
634
635 #[test]
636 fn term_literal_typed() {
637 let datatype = xsd::integer.iriref().to_string();
638 let datatype = NamedNode { iri: &datatype };
639 let t: RioTerm = Literal::Typed {
640 value: "42",
641 datatype,
642 }
643 .into();
644 assert_consistent_term_impl(&Trusted(t));
645 }
646
647 #[test]
648 fn term_triple() {
649 let subject = BlankNode { id: "foo" }.into();
650 let predicate = NamedNode { iri: "tag:bar" };
651 let object = Literal::Simple { value: "baz" }.into();
652 let tr = RioTriple {
653 subject,
654 predicate,
655 object,
656 };
657 let t = RioTerm::Triple(&tr);
658 assert_consistent_term_impl(&Trusted(t));
659 }
660
661 #[test]
662 fn gterm_blank_node() {
663 let t: RioTerm = BlankNode { id: "foo" }.into();
664 assert_consistent_term_impl(&Trusted(t))
665 }
666
667 #[test]
668 fn gterm_named_node() {
669 let t: RioTerm = NamedNode { iri: "tag:foo" }.into();
670 assert_consistent_term_impl(&Trusted(t));
671 }
672
673 #[test]
674 fn gterm_literal_simple() {
675 let t: RioTerm = Literal::Simple { value: "foo" }.into();
676 assert_consistent_term_impl(&Trusted(t));
677 }
678
679 #[test]
680 fn gterm_literal_language() {
681 let t: RioTerm = Literal::LanguageTaggedString {
682 value: "foo",
683 language: "en",
684 }
685 .into();
686 assert_consistent_term_impl(&Trusted(t));
687 }
688
689 #[test]
690 fn gterm_literal_typed() {
691 let datatype = xsd::integer.iriref().to_string();
692 let datatype = NamedNode { iri: &datatype };
693 let t: RioTerm = Literal::Typed {
694 value: "42",
695 datatype,
696 }
697 .into();
698 assert_consistent_term_impl(&Trusted(t));
699 }
700
701 #[test]
702 fn gterm_triple() {
703 let subject = BlankNode { id: "foo" }.into();
704 let predicate = NamedNode { iri: "tag:bar" };
705 let object = Literal::Simple { value: "baz" }.into();
706 let tr = RioTriple {
707 subject,
708 predicate,
709 object,
710 };
711 let t = RioTerm::Triple(&tr);
712 assert_consistent_term_impl(&Trusted(t));
713 }
714
715 #[test]
716 fn gterm_variable() {
717 let t: GeneralizedTerm = Variable { name: "foo" }.into();
718 assert_consistent_term_impl(&Trusted(t))
719 }
720}