sophia_api/term/
_cmp.rs

1use super::*;
2
3/// A wrapper for any term type that ensures comparability
4#[repr(transparent)]
5#[derive(Clone, Copy, Debug)]
6pub struct CmpTerm<T>(pub T);
7
8impl<T: Term> Term for CmpTerm<T> {
9    type BorrowTerm<'x> = CmpTerm<T::BorrowTerm<'x>> where T: 'x;
10
11    fn kind(&self) -> TermKind {
12        self.0.kind()
13    }
14    fn is_iri(&self) -> bool {
15        self.0.is_iri()
16    }
17    fn is_blank_node(&self) -> bool {
18        self.0.is_blank_node()
19    }
20    fn is_literal(&self) -> bool {
21        self.0.is_literal()
22    }
23    fn is_variable(&self) -> bool {
24        self.0.is_variable()
25    }
26    fn is_atom(&self) -> bool {
27        self.0.is_atom()
28    }
29    fn is_triple(&self) -> bool {
30        self.0.is_triple()
31    }
32    fn iri(&self) -> Option<IriRef<MownStr>> {
33        self.0.iri()
34    }
35    fn bnode_id(&self) -> Option<BnodeId<MownStr>> {
36        self.0.bnode_id()
37    }
38    fn lexical_form(&self) -> Option<MownStr> {
39        self.0.lexical_form()
40    }
41    fn datatype(&self) -> Option<IriRef<MownStr>> {
42        self.0.datatype()
43    }
44    fn language_tag(&self) -> Option<LanguageTag<MownStr>> {
45        self.0.language_tag()
46    }
47    fn variable(&self) -> Option<VarName<MownStr>> {
48        self.0.variable()
49    }
50    fn triple(&self) -> Option<[Self::BorrowTerm<'_>; 3]> {
51        self.0.triple().map(|a| a.map(CmpTerm))
52    }
53    fn to_triple(self) -> Option<[Self; 3]> {
54        self.0.to_triple().map(|a| a.map(CmpTerm))
55    }
56    fn borrow_term(&self) -> Self::BorrowTerm<'_> {
57        CmpTerm(self.0.borrow_term())
58    }
59    fn eq<U: Term>(&self, other: U) -> bool {
60        self.0.eq(other)
61    }
62    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
63        self.0.hash(state)
64    }
65    fn into_term<U: FromTerm>(self) -> U {
66        self.0.into_term()
67    }
68    fn try_into_term<U: TryFromTerm>(self) -> Result<U, U::Error> {
69        self.0.try_into_term()
70    }
71    // NOT overridding the iterator methods
72    // (constituents, to_constituents, atoms, to_atoms)
73    // because this would introduce an additional Box<dyn ...> indirection,
74    // potentially hurting performances,
75    // beyond the benefit of a hypotherical custom impl of these methods in T.
76}
77
78impl<T1: Term, T2: Term> PartialEq<T2> for CmpTerm<T1> {
79    fn eq(&self, other: &T2) -> bool {
80        Term::eq(&self.0, other.borrow_term())
81    }
82}
83
84impl<T: Term> Eq for CmpTerm<T> {}
85
86impl<T1: Term, T2: Term> PartialOrd<T2> for CmpTerm<T1> {
87    fn partial_cmp(&self, other: &T2) -> Option<Ordering> {
88        Some(Term::cmp(&self.0, other.borrow_term()))
89    }
90}
91
92impl<T: Term> Ord for CmpTerm<T> {
93    fn cmp(&self, other: &Self) -> Ordering {
94        Term::cmp(&self.0, other.borrow_term())
95    }
96}
97
98impl<T: Term> std::hash::Hash for CmpTerm<T> {
99    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
100        Term::hash(&self.0, state)
101    }
102}
103
104impl<T: Term> AsRef<T> for CmpTerm<T> {
105    fn as_ref(&self) -> &T {
106        &self.0
107    }
108}
109
110impl<T: Term> std::ops::Deref for CmpTerm<T> {
111    type Target = T;
112    fn deref(&self) -> &T {
113        &self.0
114    }
115}
116
117impl<T: Term + FromTerm> FromTerm for CmpTerm<T> {
118    fn from_term<U: Term>(term: U) -> Self {
119        Self(term.into_term())
120    }
121}
122
123impl<T: Term + TryFromTerm> TryFromTerm for CmpTerm<T> {
124    type Error = T::Error;
125
126    fn try_from_term<U: Term>(term: U) -> Result<Self, Self::Error> {
127        term.try_into_term().map(Self)
128    }
129}