1use crate::{
4 CowTerm, HeapTerm, Quad, QuadPattern, Statement, StatementPattern, Term, TriplePattern,
5};
6
7pub type TripleSlot = crate::StatementSlot;
8
9#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct Triple<T: Term> {
13 pub(crate) s: T,
14 pub(crate) p: T,
15 pub(crate) o: T,
16}
17
18impl<T: Term> Triple<T> {
19 pub const fn new(s: T, p: T, o: T) -> Self {
20 Self { s, p, o }
21 }
22
23 pub fn with_subject(self, s: impl Into<T>) -> Self {
24 Self {
25 s: s.into(),
26 ..self
27 }
28 }
29
30 pub fn with_predicate(self, p: impl Into<T>) -> Self {
31 Self {
32 p: p.into(),
33 ..self
34 }
35 }
36
37 pub fn with_object(self, o: impl Into<T>) -> Self {
38 Self {
39 o: o.into(),
40 ..self
41 }
42 }
43
44 pub fn with_context(self, g: impl Into<Option<T>>) -> Quad<T> {
45 Quad::new(self.s, self.p, self.o, g.into())
46 }
47
48 pub fn into_inner(self) -> (T, T, T) {
49 (self.s, self.p, self.o)
50 }
51
52 pub fn has_subject(&self) -> bool {
54 true
55 }
56
57 pub fn has_predicate(&self) -> bool {
59 true
60 }
61
62 pub fn has_object(&self) -> bool {
64 true
65 }
66
67 pub fn has_context(&self) -> bool {
69 false
70 }
71
72 pub fn subject(&self) -> &T {
73 &self.s
74 }
75
76 pub fn predicate(&self) -> &T {
77 &self.p
78 }
79
80 pub fn object(&self) -> &T {
81 &self.o
82 }
83
84 pub fn context(&self) -> Option<&T> {
85 None
86 }
87}
88
89impl<T: Term + Clone> Statement for Triple<T> {
90 type Term = T;
91
92 fn subject(&self) -> &Self::Term {
93 &self.s
94 }
95
96 fn predicate(&self) -> &Self::Term {
97 &self.p
98 }
99
100 fn object(&self) -> &Self::Term {
101 &self.o
102 }
103}
104
105impl<T: Term + Clone> StatementPattern for Triple<T> {
106 type Term = T;
107
108 fn subject(&self) -> Option<&Self::Term> {
109 Some(&self.s)
110 }
111
112 fn predicate(&self) -> Option<&Self::Term> {
113 Some(&self.p)
114 }
115
116 fn object(&self) -> Option<&Self::Term> {
117 Some(&self.o)
118 }
119}
120
121impl<T: Term + Clone> Triple<T> {
122 pub fn to_triple_pattern(&self) -> TriplePattern<T> {
123 TriplePattern::new(
124 Some(self.s.clone()),
125 Some(self.p.clone()),
126 Some(self.o.clone()),
127 )
128 }
129
130 pub fn to_quad(&self) -> Quad<T> {
131 Quad::new(self.s.clone(), self.p.clone(), self.o.clone(), None)
132 }
133
134 pub fn to_quad_pattern(&self) -> QuadPattern<T> {
135 QuadPattern::new(
136 Some(self.s.clone()),
137 Some(self.p.clone()),
138 Some(self.o.clone()),
139 None,
140 )
141 }
142}
143
144impl From<Triple<CowTerm<'_>>> for Triple<HeapTerm> {
145 fn from(input: Triple<CowTerm<'_>>) -> Self {
146 Self::new(input.s.into(), input.p.into(), input.o.into())
147 }
148}
149
150impl<'a> From<&'a Triple<CowTerm<'a>>> for Triple<HeapTerm> {
151 fn from(input: &'a Triple<CowTerm<'a>>) -> Self {
152 Self::new((&input.s).into(), (&input.p).into(), (&input.o).into())
153 }
154}
155
156impl From<Quad<CowTerm<'_>>> for Triple<HeapTerm> {
157 fn from(input: Quad<CowTerm<'_>>) -> Self {
158 Self::new(input.s.into(), input.p.into(), input.o.into())
159 }
160}
161
162impl<'a> From<&'a Quad<CowTerm<'a>>> for Triple<HeapTerm> {
163 fn from(input: &'a Quad<CowTerm<'a>>) -> Self {
164 Self::new((&input.s).into(), (&input.p).into(), (&input.o).into())
165 }
166}
167
168impl<'a> From<Triple<HeapTerm>> for Triple<CowTerm<'a>> {
169 fn from(input: Triple<HeapTerm>) -> Self {
170 Self::new(input.s.into(), input.p.into(), input.o.into())
171 }
172}
173
174impl<'a> From<&'a Triple<HeapTerm>> for Triple<CowTerm<'a>> {
175 fn from(input: &'a Triple<HeapTerm>) -> Self {
176 Self::new((&input.s).into(), (&input.p).into(), (&input.o).into())
177 }
178}
179
180impl<'a> From<Quad<HeapTerm>> for Triple<CowTerm<'a>> {
181 fn from(input: Quad<HeapTerm>) -> Self {
182 Self::new(input.s.into(), input.p.into(), input.o.into())
183 }
184}
185
186impl<'a> From<&'a Quad<HeapTerm>> for Triple<CowTerm<'a>> {
187 fn from(input: &'a Quad<HeapTerm>) -> Self {
188 Self::new((&input.s).into(), (&input.p).into(), (&input.o).into())
189 }
190}
191
192impl<T: Term> From<(T, T, T)> for Triple<T> {
193 fn from((s, p, o): (T, T, T)) -> Self {
194 Self::new(s, p, o)
195 }
196}
197
198impl<T: Term + Clone> From<(&T, &T, &T)> for Triple<T> {
199 fn from((s, p, o): (&T, &T, &T)) -> Self {
200 Self::new(s.clone(), p.clone(), o.clone())
201 }
202}
203
204impl<T: Term> TryFrom<TriplePattern<T>> for Triple<T> {
205 type Error = ();
206
207 fn try_from(input: TriplePattern<T>) -> Result<Self, Self::Error> {
208 if !input.is_constant() {
209 return Err(());
210 }
211 Ok(Self::new(
212 input.s.unwrap(),
213 input.p.unwrap(),
214 input.o.unwrap(),
215 ))
216 }
217}
218
219impl<T: Term> TryFrom<QuadPattern<T>> for Triple<T> {
220 type Error = ();
221
222 fn try_from(input: QuadPattern<T>) -> Result<Self, Self::Error> {
223 if !input.is_constant() {
224 return Err(());
225 }
226 Ok(Self::new(
227 input.s.unwrap(),
228 input.p.unwrap(),
229 input.o.unwrap(),
230 ))
231 }
232}
233
234impl<T: Term> FromIterator<T> for Triple<T> {
235 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
236 let mut iter = iter.into_iter();
237 Self::new(
238 iter.next().unwrap(),
239 iter.next().unwrap(),
240 iter.next().unwrap(),
241 )
242 }
243}