rdf_model/
triple_pattern.rs1use crate::{CowTerm, HeapTerm, QuadPattern, StatementPattern, Term};
4
5pub static EMPTY_COW_TRIPLE_PATTERN: TriplePattern<CowTerm> = TriplePattern::EMPTY;
6pub static EMPTY_HEAP_TRIPLE_PATTERN: TriplePattern<HeapTerm> = TriplePattern::EMPTY;
7
8#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct TriplePattern<T: Term> {
12 pub(crate) s: Option<T>,
13 pub(crate) p: Option<T>,
14 pub(crate) o: Option<T>,
15}
16
17impl<T: Term> Default for TriplePattern<T> {
18 fn default() -> Self {
19 Self::EMPTY
20 }
21}
22
23impl<T: Term> TriplePattern<T> {
24 pub const EMPTY: TriplePattern<T> = Self::empty();
25
26 pub const fn empty() -> Self {
27 Self::new(None, None, None)
28 }
29
30 pub const fn new(s: Option<T>, p: Option<T>, o: Option<T>) -> Self {
31 Self { s, p, o }
32 }
33
34 pub const fn with_subject(s: T) -> Self {
35 Self::new(Some(s), None, None)
36 }
37
38 pub const fn with_predicate(p: T) -> Self {
39 Self::new(None, Some(p), None)
40 }
41
42 pub const fn with_object(o: T) -> Self {
43 Self::new(None, None, Some(o))
44 }
45
46 pub fn is_empty(&self) -> bool {
47 self.s.is_none() && self.p.is_none() && self.o.is_none()
48 }
49
50 pub fn is_constant(&self) -> bool {
51 self.s.is_some() && self.p.is_some() && self.o.is_some()
52 }
53
54 pub fn is_variable(&self) -> bool {
55 !self.is_constant()
56 }
57
58 pub fn into_inner(self) -> (Option<T>, Option<T>, Option<T>) {
59 (self.s, self.p, self.o)
60 }
61}
62
63impl<T: Term + Clone> TriplePattern<T> {
64 pub fn to_quad_pattern(&self) -> QuadPattern<T> {
65 QuadPattern::new(self.s.clone(), self.p.clone(), self.o.clone(), None)
66 }
67}
68
69impl<T: Term + Clone> StatementPattern for TriplePattern<T> {
70 type Term = T;
71
72 fn subject(&self) -> Option<&Self::Term> {
73 self.s.as_ref()
74 }
75
76 fn predicate(&self) -> Option<&Self::Term> {
77 self.p.as_ref()
78 }
79
80 fn object(&self) -> Option<&Self::Term> {
81 self.o.as_ref()
82 }
83
84 fn context(&self) -> Option<&Self::Term> {
85 None
86 }
87}
88
89impl<T: Term> From<()> for TriplePattern<T> {
90 fn from(_: ()) -> Self {
91 Self::default()
92 }
93}
94
95impl<T: Term> From<Option<()>> for TriplePattern<T> {
96 fn from(_: Option<()>) -> Self {
97 Self::default()
98 }
99}
100
101impl<T: Term> From<(T, T, T)> for TriplePattern<T> {
102 fn from((s, p, o): (T, T, T)) -> Self {
103 Self::from((Some(s), Some(p), Some(o)))
104 }
105}
106
107impl<T: Term> From<(Option<T>, Option<T>, Option<T>)> for TriplePattern<T> {
108 fn from((s, p, o): (Option<T>, Option<T>, Option<T>)) -> Self {
109 Self { s, p, o }
110 }
111}
112
113impl<T: Term + Clone> From<(&T, &T, &T)> for TriplePattern<T> {
114 fn from((s, p, o): (&T, &T, &T)) -> Self {
115 Self::from((Some(s), Some(p), Some(o)))
116 }
117}
118
119impl<T: Term + Clone> From<(Option<&T>, Option<&T>, Option<&T>)> for TriplePattern<T> {
120 fn from((s, p, o): (Option<&T>, Option<&T>, Option<&T>)) -> Self {
121 Self {
122 s: s.cloned(),
123 p: p.cloned(),
124 o: o.cloned(),
125 }
126 }
127}
128
129impl<T: Term> FromIterator<T> for TriplePattern<T> {
130 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
131 let mut iter = iter.into_iter();
132 Self::new(
133 Some(iter.next().unwrap()),
134 Some(iter.next().unwrap()),
135 Some(iter.next().unwrap()),
136 )
137 }
138}