Skip to main content

rdf_types/dataset/graph/
mod.rs

1//! RDF graph traits and implementations.
2use crate::{Triple, pattern::LinearTriplePattern};
3
4mod r#async;
5mod fallible;
6mod r#impl;
7
8pub use r#async::*;
9pub use fallible::*;
10pub use r#impl::*;
11
12/// RDF graph.
13///
14/// A graph is a set of [`Triple`]s. This trait only fixes the resource
15/// type; see [`FiniteGraph`] and the other traits of this module for
16/// actually usable graphs.
17pub trait Graph {
18	/// Resource type.
19	type Resource;
20}
21
22/// Graph that can be traversed using a provided triple iterator.
23pub trait FiniteGraph: Graph {
24	/// Triples iterator.
25	type Triples<'a>: Iterator<Item = Triple<&'a Self::Resource>>
26	where
27		Self: 'a;
28
29	/// Returns an iterator over the triples of the graph.
30	fn triples(&self) -> Self::Triples<'_>;
31
32	/// Returns the number of triples in the graph.
33	fn triples_count(&self) -> usize {
34		self.triples().count()
35	}
36}
37
38/// Graph that can enumerate the distinct resources it mentions (in any
39/// position of any triple).
40pub trait ResourceFiniteGraph: Graph {
41	/// Resources iterator.
42	type GraphResources<'a>: Iterator<Item = &'a Self::Resource>
43	where
44		Self: 'a;
45
46	/// Returns an iterator over the distinct resources of the graph.
47	fn graph_resources(&self) -> Self::GraphResources<'_>;
48
49	/// Returns the number of distinct resources in the graph.
50	fn graph_resource_count(&self) -> usize {
51		self.graph_resources().count()
52	}
53}
54
55/// Graph that can enumerate the distinct resources it uses as a subject.
56pub trait SubjectFiniteGraph: Graph {
57	/// Subjects iterator.
58	type GraphSubjects<'a>: Iterator<Item = &'a Self::Resource>
59	where
60		Self: 'a;
61
62	/// Returns an iterator over the distinct subjects of the graph.
63	fn graph_subjects(&self) -> Self::GraphSubjects<'_>;
64
65	/// Returns the number of distinct subjects in the graph.
66	fn graph_subject_count(&self) -> usize {
67		self.graph_subjects().count()
68	}
69}
70
71/// Graph that can enumerate the distinct resources it uses as a predicate.
72pub trait PredicateFiniteGraph: Graph {
73	/// Predicates iterator.
74	type GraphPredicates<'a>: Iterator<Item = &'a Self::Resource>
75	where
76		Self: 'a;
77
78	/// Returns an iterator over the distinct predicates of the graph.
79	fn graph_predicates(&self) -> Self::GraphPredicates<'_>;
80
81	/// Returns the number of distinct predicates in the graph.
82	fn graph_predicate_count(&self) -> usize {
83		self.graph_predicates().count()
84	}
85}
86
87/// Graph that can enumerate the distinct resources it uses as an object.
88pub trait ObjectFiniteGraph: Graph {
89	/// Objects iterator.
90	type GraphObjects<'a>: Iterator<Item = &'a Self::Resource>
91	where
92		Self: 'a;
93
94	/// Returns an iterator over the distinct objects of the graph.
95	fn graph_objects(&self) -> Self::GraphObjects<'_>;
96
97	/// Returns the number of distinct objects in the graph.
98	fn graph_object_count(&self) -> usize {
99		self.graph_objects().count()
100	}
101}
102
103/// Multi-pattern-matching-capable graph.
104///
105/// Unlike [`PatternMatchingGraph`], each component of the pattern may match
106/// any resource from a given set, rather than at most one fixed resource.
107pub trait MultiPatternMatchingGraph: Graph {
108	/// Pattern-matching iterator.
109	type TripleMultiPatternMatching<'a, 'p>: Iterator<Item = Triple<&'a Self::Resource>>
110	where
111		Self: 'a,
112		Self::Resource: 'p;
113
114	/// Returns an iterator over all the triples of the graph matching the
115	/// given pattern.
116	fn triple_multi_pattern_matching<'p, P: IntoIterator<Item = &'p Self::Resource>>(
117		&self,
118		pattern: LinearTriplePattern<P>,
119	) -> Self::TripleMultiPatternMatching<'_, 'p>;
120}
121
122/// Pattern-matching-capable graph.
123///
124/// A graph that can be queried with a [`LinearTriplePattern`], i.e. a triple
125/// where each component is either a fixed resource or left unconstrained.
126pub trait PatternMatchingGraph: Graph {
127	/// Pattern-matching iterator.
128	type TriplePatternMatching<'a, 'p>: Iterator<Item = Triple<&'a Self::Resource>>
129	where
130		Self: 'a,
131		Self::Resource: 'p;
132
133	/// Returns an iterator over all the triples of the graph matching the
134	/// given pattern.
135	fn triple_pattern_matching<'p>(
136		&self,
137		pattern: LinearTriplePattern<&'p Self::Resource>,
138	) -> Self::TriplePatternMatching<'_, 'p>;
139
140	/// Checks if the graph contains the given triple.
141	fn contains_triple(&self, triple: Triple<&Self::Resource>) -> bool {
142		self.triple_pattern_matching(triple.into()).next().is_some()
143	}
144
145	/// Checks if the graph contains the given subject.
146	fn contains_triple_subject(&self, subject: &Self::Resource) -> bool {
147		self.triple_pattern_matching(Triple(Some(subject), None, None))
148			.next()
149			.is_some()
150	}
151
152	/// Checks if the graph contains the given predicate.
153	fn contains_triple_predicate(&self, predicate: &Self::Resource) -> bool {
154		self.triple_pattern_matching(Triple(None, Some(predicate), None))
155			.next()
156			.is_some()
157	}
158
159	/// Checks if the graph contains the given object.
160	fn contains_triple_object(&self, object: &Self::Resource) -> bool {
161		self.triple_pattern_matching(Triple(None, None, Some(object)))
162			.next()
163			.is_some()
164	}
165
166	/// Returns an iterator over all the predicates `p` matching the triple `subject p o` present in the graph, for some `o`.
167	fn triple_predicates_objects<'p>(
168		&self,
169		subject: &'p Self::Resource,
170	) -> TriplePredicatesObjects<'_, 'p, Self>
171	where
172		Self: PredicateFiniteGraph,
173		Self::Resource: 'p,
174	{
175		TriplePredicatesObjects {
176			subject,
177			predicates: self.graph_predicates(),
178			graph: self,
179		}
180	}
181
182	/// Returns an iterator over all the objects `o` matching the triple `subject predicate o` present in the graph.
183	fn triple_objects<'p>(
184		&self,
185		subject: &'p Self::Resource,
186		predicate: &'p Self::Resource,
187	) -> TripleObjects<'_, 'p, Self> {
188		TripleObjects {
189			first: None,
190			inner: self.triple_pattern_matching(Triple(Some(subject), Some(predicate), None)),
191		}
192	}
193}
194
195/// Iterator over the predicates of a graph matching a given subject, along
196/// with, for each predicate, the objects matching it.
197///
198/// Created by [`PatternMatchingGraph::triple_predicates_objects`].
199pub struct TriplePredicatesObjects<
200	'a,
201	'p,
202	G: 'a + ?Sized + PredicateFiniteGraph + PatternMatchingGraph,
203> {
204	subject: &'p G::Resource,
205	predicates: G::GraphPredicates<'a>,
206	graph: &'a G,
207}
208
209impl<'a: 'p, 'p, G: 'a + ?Sized + PredicateFiniteGraph + PatternMatchingGraph> Iterator
210	for TriplePredicatesObjects<'a, 'p, G>
211where
212	G::Resource: 'p,
213{
214	type Item = (&'a G::Resource, TripleObjects<'p, 'p, G>);
215
216	fn next(&mut self) -> Option<Self::Item> {
217		for predicate in &mut self.predicates {
218			let pattern = Triple(Some(self.subject), Some(predicate), None);
219
220			let mut iter = self.graph.triple_pattern_matching(pattern);
221			if let Some(Triple(_, _, o)) = iter.next() {
222				return Some((
223					predicate,
224					TripleObjects {
225						first: Some(o),
226						inner: iter,
227					},
228				));
229			}
230		}
231
232		None
233	}
234}
235
236/// Iterator over the objects of a graph matching a given subject and
237/// predicate.
238///
239/// Created by [`PatternMatchingGraph::triple_objects`].
240pub struct TripleObjects<'a, 'p, D: 'a + ?Sized + PatternMatchingGraph>
241where
242	D::Resource: 'p,
243{
244	first: Option<&'a D::Resource>,
245	inner: D::TriplePatternMatching<'a, 'p>,
246}
247
248impl<'a, 'p, D: 'a + ?Sized + PatternMatchingGraph> Iterator for TripleObjects<'a, 'p, D>
249where
250	D::Resource: 'p,
251{
252	type Item = &'a D::Resource;
253
254	fn next(&mut self) -> Option<Self::Item> {
255		self.first
256			.take()
257			.or_else(|| self.inner.next().map(Triple::into_object))
258	}
259}
260
261/// Pattern-matching-capable mutable graph.
262pub trait PatternMatchingGraphMut: PatternMatchingGraph {
263	/// Pattern-matching iterator.
264	type ExtractMatchingTriples<'a, 'p>: Iterator<Item = Triple<Self::Resource>>
265	where
266		Self: 'a,
267		Self::Resource: 'p;
268
269	/// Returns an iterator over all the triples matching the given linear
270	/// triple pattern.
271	///
272	/// Each matching triple returned by [`Iterator::next`] are removed from
273	/// the graph. Matching triples that are not iterated on are kept in the
274	/// graph, even when the iterator is dropped.
275	fn extract_matching_triples<'p>(
276		&mut self,
277		pattern: impl Into<LinearTriplePattern<&'p Self::Resource>>,
278	) -> Self::ExtractMatchingTriples<'_, 'p>
279	where
280		Self::Resource: 'p;
281}
282
283/// Mutable graph.
284pub trait GraphMut: Graph {
285	/// Inserts the given triple in the graph.
286	fn insert(&mut self, triple: Triple<Self::Resource>);
287
288	/// Removes the given triple from the graph.
289	fn remove(&mut self, triple: Triple<&Self::Resource>);
290}