rdf_types/
triple.rs

1use std::{cmp::Ordering, fmt};
2
3use iref::{Iri, IriBuf};
4
5use crate::{
6	vocabulary::{
7		ByRef, EmbedIntoVocabulary, EmbeddedIntoVocabulary, ExtractFromVocabulary,
8		ExtractedFromVocabulary,
9	},
10	Id, LexicalObjectRef, LexicalSubjectRef, Object, Quad, RdfDisplay, Term,
11};
12
13#[cfg(feature = "contextual")]
14use contextual::{DisplayWithContext, WithContext};
15
16#[cfg(feature = "contextual")]
17use crate::RdfDisplayWithContext;
18
19/// Lexical RDF triple.
20pub type LexicalTriple = Triple<Id, IriBuf, Object>;
21
22/// Lexical RDF triple reference.
23pub type LexicalTripleRef<'a> = Triple<LexicalSubjectRef<'a>, &'a Iri, LexicalObjectRef<'a>>;
24
25/// RDF triple.
26#[derive(Clone, Copy, Eq, Ord, Hash, Debug)]
27#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28pub struct Triple<S = Term, P = S, O = S>(pub S, pub P, pub O);
29
30impl<S1: PartialEq<S2>, P1: PartialEq<P2>, O1: PartialEq<O2>, S2, P2, O2>
31	PartialEq<Triple<S2, P2, O2>> for Triple<S1, P1, O1>
32{
33	fn eq(&self, other: &Triple<S2, P2, O2>) -> bool {
34		self.0 == other.0 && self.1 == other.1 && self.2 == other.2
35	}
36}
37
38impl<S1: PartialOrd<S2>, P1: PartialOrd<P2>, O1: PartialOrd<O2>, S2, P2, O2>
39	PartialOrd<Triple<S2, P2, O2>> for Triple<S1, P1, O1>
40{
41	fn partial_cmp(&self, other: &Triple<S2, P2, O2>) -> Option<Ordering> {
42		match self.0.partial_cmp(&other.0) {
43			Some(Ordering::Equal) => match self.1.partial_cmp(&other.1) {
44				Some(Ordering::Equal) => self.2.partial_cmp(&other.2),
45				cmp => cmp,
46			},
47			cmp => cmp,
48		}
49	}
50}
51
52impl<S, P, O> Triple<S, P, O> {
53	/// Creates a new triple.
54	pub fn new(subject: S, predicate: P, object: O) -> Self {
55		Self(subject, predicate, object)
56	}
57
58	/// Returns a reference to the subject of the triple,
59	/// the first component.
60	pub fn subject(&self) -> &S {
61		&self.0
62	}
63
64	/// Returns a mutable reference to the subject of the triple,
65	/// the first component.
66	pub fn subject_mut(&mut self) -> &mut S {
67		&mut self.0
68	}
69
70	/// Turns the triple into its subject,
71	/// the first component.
72	pub fn into_subject(self) -> S {
73		self.0
74	}
75
76	/// Returns a reference to the predicate of the triple,
77	/// the second component.
78	pub fn predicate(&self) -> &P {
79		&self.1
80	}
81
82	/// Returns a mutable reference to the predicate of the triple,
83	/// the second component.
84	pub fn predicate_mut(&mut self) -> &mut P {
85		&mut self.1
86	}
87
88	/// Turns the triple into its predicate,
89	/// the second component.
90	pub fn into_predicate(self) -> P {
91		self.1
92	}
93
94	/// Returns a reference to the object of the triple,
95	/// the third component.
96	pub fn object(&self) -> &O {
97		&self.2
98	}
99
100	/// Returns a mutable reference to the object of the triple,
101	/// the third component.
102	pub fn object_mut(&mut self) -> &mut O {
103		&mut self.2
104	}
105
106	/// Turns the triple into its object,
107	/// the third component.
108	pub fn into_object(self) -> O {
109		self.2
110	}
111
112	/// Turns the triple into a tuple
113	pub fn into_parts(self) -> (S, P, O) {
114		(self.0, self.1, self.2)
115	}
116
117	/// Turns the triple into a quad with the given `graph` component.
118	pub fn into_quad<G>(self, graph: Option<G>) -> Quad<S, P, O, G> {
119		Quad(self.0, self.1, self.2, graph)
120	}
121
122	/// Maps the subject with the given function.
123	pub fn map_subject<U>(self, f: impl FnOnce(S) -> U) -> Triple<U, P, O> {
124		Triple(f(self.0), self.1, self.2)
125	}
126
127	/// Maps the subject with the given function.
128	pub fn map_predicate<U>(self, f: impl FnOnce(P) -> U) -> Triple<S, U, O> {
129		Triple(self.0, f(self.1), self.2)
130	}
131
132	/// Maps the subject with the given function.
133	pub fn map_object<U>(self, f: impl FnOnce(O) -> U) -> Triple<S, P, U> {
134		Triple(self.0, self.1, f(self.2))
135	}
136
137	/// Borrows each component of the triple.
138	pub fn as_ref(&self) -> Triple<&S, &P, &O> {
139		Triple(&self.0, &self.1, &self.2)
140	}
141}
142
143impl<S, P, O> Triple<&S, &P, &O> {
144	pub fn cloned(&self) -> Triple<S, P, O>
145	where
146		S: Clone,
147		P: Clone,
148		O: Clone,
149	{
150		Triple(self.0.clone(), self.1.clone(), self.2.clone())
151	}
152
153	pub fn into_cloned(self) -> Triple<S, P, O>
154	where
155		S: Clone,
156		P: Clone,
157		O: Clone,
158	{
159		Triple(self.0.clone(), self.1.clone(), self.2.clone())
160	}
161}
162
163impl<S, P, O> Triple<&S, &P, &O> {
164	pub fn copied(&self) -> Triple<S, P, O>
165	where
166		S: Copy,
167		P: Copy,
168		O: Copy,
169	{
170		Triple(*self.0, *self.1, *self.2)
171	}
172
173	pub fn into_copied(self) -> Triple<S, P, O>
174	where
175		S: Copy,
176		P: Copy,
177		O: Copy,
178	{
179		Triple(*self.0, *self.1, *self.2)
180	}
181}
182
183impl<T> Triple<T, T, T> {
184	/// Maps the components with the given function.
185	pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Triple<U, U, U> {
186		Triple(f(self.0), f(self.1), f(self.2))
187	}
188}
189
190impl LexicalTriple {
191	pub fn as_lexical_triple_ref(&self) -> LexicalTripleRef {
192		Triple(
193			self.0.as_lexical_subject_ref(),
194			self.1.as_iri(),
195			self.2.as_lexical_object_ref(),
196		)
197	}
198}
199
200impl LexicalTripleRef<'_> {
201	pub fn into_owned(self) -> LexicalTriple {
202		Triple(self.0.into_owned(), self.1.to_owned(), self.2.into_owned())
203	}
204}
205
206impl<V, S: ExtractFromVocabulary<V>, P: ExtractFromVocabulary<V>, O: ExtractFromVocabulary<V>>
207	ExtractFromVocabulary<V> for Triple<S, P, O>
208{
209	type Extracted = Triple<S::Extracted, P::Extracted, O::Extracted>;
210
211	fn extract_from_vocabulary(self, vocabulary: &V) -> Self::Extracted {
212		Triple(
213			self.0.extract_from_vocabulary(vocabulary),
214			self.1.extract_from_vocabulary(vocabulary),
215			self.2.extract_from_vocabulary(vocabulary),
216		)
217	}
218}
219
220impl<V, S, P, O> ExtractFromVocabulary<V> for ByRef<Triple<S, P, O>>
221where
222	ByRef<S>: ExtractFromVocabulary<V>,
223	ByRef<P>: ExtractFromVocabulary<V>,
224	ByRef<O>: ExtractFromVocabulary<V>,
225{
226	type Extracted = Triple<
227		<ByRef<S> as ExtractFromVocabulary<V>>::Extracted,
228		<ByRef<P> as ExtractFromVocabulary<V>>::Extracted,
229		<ByRef<O> as ExtractFromVocabulary<V>>::Extracted,
230	>;
231
232	fn extract_from_vocabulary(self, vocabulary: &V) -> Self::Extracted {
233		Triple(
234			ByRef(self.0 .0).extract_from_vocabulary(vocabulary),
235			ByRef(self.0 .1).extract_from_vocabulary(vocabulary),
236			ByRef(self.0 .2).extract_from_vocabulary(vocabulary),
237		)
238	}
239}
240
241impl<
242		V,
243		S: ExtractedFromVocabulary<V>,
244		P: ExtractedFromVocabulary<V>,
245		O: ExtractedFromVocabulary<V>,
246	> ExtractedFromVocabulary<V> for Triple<S, P, O>
247{
248	type Extracted = Triple<S::Extracted, P::Extracted, O::Extracted>;
249
250	fn extracted_from_vocabulary(&self, vocabulary: &V) -> Self::Extracted {
251		Triple(
252			self.0.extracted_from_vocabulary(vocabulary),
253			self.1.extracted_from_vocabulary(vocabulary),
254			self.2.extracted_from_vocabulary(vocabulary),
255		)
256	}
257}
258
259impl<V, S: EmbedIntoVocabulary<V>, P: EmbedIntoVocabulary<V>, O: EmbedIntoVocabulary<V>>
260	EmbedIntoVocabulary<V> for Triple<S, P, O>
261{
262	type Embedded = Triple<S::Embedded, P::Embedded, O::Embedded>;
263
264	fn embed_into_vocabulary(self, vocabulary: &mut V) -> Self::Embedded {
265		Triple(
266			self.0.embed_into_vocabulary(vocabulary),
267			self.1.embed_into_vocabulary(vocabulary),
268			self.2.embed_into_vocabulary(vocabulary),
269		)
270	}
271}
272
273impl<
274		V,
275		S: EmbeddedIntoVocabulary<V>,
276		P: EmbeddedIntoVocabulary<V>,
277		O: EmbeddedIntoVocabulary<V>,
278	> EmbeddedIntoVocabulary<V> for Triple<S, P, O>
279{
280	type Embedded = Triple<S::Embedded, P::Embedded, O::Embedded>;
281
282	fn embedded_into_vocabulary(&self, vocabulary: &mut V) -> Self::Embedded {
283		Triple(
284			self.0.embedded_into_vocabulary(vocabulary),
285			self.1.embedded_into_vocabulary(vocabulary),
286			self.2.embedded_into_vocabulary(vocabulary),
287		)
288	}
289}
290
291impl<S: RdfDisplay, P: RdfDisplay, O: RdfDisplay> fmt::Display for Triple<S, P, O> {
292	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
293		write!(
294			f,
295			"{} {} {}",
296			self.0.rdf_display(),
297			self.1.rdf_display(),
298			self.2.rdf_display()
299		)
300	}
301}
302
303impl<S: RdfDisplay, P: RdfDisplay, O: RdfDisplay> RdfDisplay for Triple<S, P, O> {
304	fn rdf_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
305		write!(
306			f,
307			"{} {} {}",
308			self.0.rdf_display(),
309			self.1.rdf_display(),
310			self.2.rdf_display()
311		)
312	}
313}
314
315#[cfg(feature = "contextual")]
316impl<S: RdfDisplayWithContext<V>, P: RdfDisplayWithContext<V>, O: RdfDisplayWithContext<V>, V>
317	DisplayWithContext<V> for Triple<S, P, O>
318{
319	fn fmt_with(&self, vocabulary: &V, f: &mut fmt::Formatter) -> fmt::Result {
320		write!(
321			f,
322			"{} {} {}",
323			self.0.with(vocabulary).rdf_display(),
324			self.1.with(vocabulary).rdf_display(),
325			self.2.with(vocabulary).rdf_display()
326		)
327	}
328}
329
330#[cfg(feature = "contextual")]
331impl<S: RdfDisplayWithContext<V>, P: RdfDisplayWithContext<V>, O: RdfDisplayWithContext<V>, V>
332	RdfDisplayWithContext<V> for Triple<S, P, O>
333{
334	fn rdf_fmt_with(&self, vocabulary: &V, f: &mut fmt::Formatter) -> fmt::Result {
335		write!(
336			f,
337			"{} {} {}",
338			self.0.with(vocabulary).rdf_display(),
339			self.1.with(vocabulary).rdf_display(),
340			self.2.with(vocabulary).rdf_display()
341		)
342	}
343}