1use crate::{
3 pattern::{quad::canonical::PatternGraph, CanonicalQuadPattern},
4 utils::{OptionIterator, TripleToQuadIterator},
5 Quad,
6};
7
8pub mod fallible;
9pub use fallible::FallibleDataset;
10
11mod graph;
12pub use graph::{fallible as fallible_graph, *};
13
14mod r#impl;
15pub use r#impl::*;
16
17pub mod isomorphism;
18
19pub trait Dataset {
21 type Resource;
23}
24
25impl<G: Graph> Dataset for G {
26 type Resource = G::Resource;
27}
28
29pub trait TraversableDataset: Dataset {
31 type Quads<'a>: Iterator<Item = Quad<&'a Self::Resource>>
33 where
34 Self: 'a;
35
36 fn quads(&self) -> Self::Quads<'_>;
38
39 fn quads_count(&self) -> usize {
40 self.quads().count()
41 }
42}
43
44impl<G: TraversableGraph> TraversableDataset for G {
45 type Quads<'a>
46 = TripleToQuadIterator<G::Triples<'a>, &'a G::Resource>
47 where
48 Self: 'a;
49
50 fn quads(&self) -> Self::Quads<'_> {
51 TripleToQuadIterator::new(self.triples())
52 }
53
54 fn quads_count(&self) -> usize {
55 TraversableGraph::triples_count(self)
56 }
57}
58
59pub trait ResourceTraversableDataset: Dataset {
60 type Resources<'a>: Iterator<Item = &'a Self::Resource>
61 where
62 Self: 'a;
63
64 fn resources(&self) -> Self::Resources<'_>;
65
66 fn resource_count(&self) -> usize {
67 self.resources().count()
68 }
69}
70
71impl<G: ResourceTraversableGraph> ResourceTraversableDataset for G {
72 type Resources<'a>
73 = G::GraphResources<'a>
74 where
75 Self: 'a;
76
77 fn resources(&self) -> Self::Resources<'_> {
78 self.graph_resources()
79 }
80
81 fn resource_count(&self) -> usize {
82 self.graph_resource_count()
83 }
84}
85
86pub trait SubjectTraversableDataset: Dataset {
87 type Subjects<'a>: Iterator<Item = &'a Self::Resource>
88 where
89 Self: 'a;
90
91 fn subjects(&self) -> Self::Subjects<'_>;
92
93 fn subject_count(&self) -> usize {
94 self.subjects().count()
95 }
96}
97
98impl<G: SubjectTraversableGraph> SubjectTraversableDataset for G {
99 type Subjects<'a>
100 = G::GraphSubjects<'a>
101 where
102 Self: 'a;
103
104 fn subjects(&self) -> Self::Subjects<'_> {
105 self.graph_subjects()
106 }
107
108 fn subject_count(&self) -> usize {
109 self.graph_subject_count()
110 }
111}
112
113pub trait PredicateTraversableDataset: Dataset {
114 type Predicates<'a>: Iterator<Item = &'a Self::Resource>
115 where
116 Self: 'a;
117
118 fn predicates(&self) -> Self::Predicates<'_>;
119
120 fn predicate_count(&self) -> usize {
121 self.predicates().count()
122 }
123}
124
125impl<G: PredicateTraversableGraph> PredicateTraversableDataset for G {
126 type Predicates<'a>
127 = G::GraphPredicates<'a>
128 where
129 Self: 'a;
130
131 fn predicates(&self) -> Self::Predicates<'_> {
132 self.graph_predicates()
133 }
134
135 fn predicate_count(&self) -> usize {
136 self.graph_predicate_count()
137 }
138}
139
140pub trait ObjectTraversableDataset: Dataset {
141 type Objects<'a>: Iterator<Item = &'a Self::Resource>
142 where
143 Self: 'a;
144
145 fn objects(&self) -> Self::Objects<'_>;
146
147 fn object_count(&self) -> usize {
148 self.objects().count()
149 }
150}
151
152impl<G: ObjectTraversableGraph> ObjectTraversableDataset for G {
153 type Objects<'a>
154 = G::GraphObjects<'a>
155 where
156 Self: 'a;
157
158 fn objects(&self) -> Self::Objects<'_> {
159 self.graph_objects()
160 }
161
162 fn object_count(&self) -> usize {
163 self.graph_object_count()
164 }
165}
166
167pub trait NamedGraphTraversableDataset: Dataset {
168 type NamedGraphs<'a>: Iterator<Item = &'a Self::Resource>
169 where
170 Self: 'a;
171
172 fn named_graphs(&self) -> Self::NamedGraphs<'_>;
173
174 fn named_graph_count(&self) -> usize {
175 self.named_graphs().count()
176 }
177}
178
179impl<G: Graph> NamedGraphTraversableDataset for G {
180 type NamedGraphs<'a>
181 = std::iter::Empty<&'a Self::Resource>
182 where
183 Self: 'a;
184
185 fn named_graphs(&self) -> Self::NamedGraphs<'_> {
186 std::iter::empty()
187 }
188
189 fn named_graph_count(&self) -> usize {
190 0
191 }
192}
193
194pub trait PatternMatchingDataset: Dataset {
196 type QuadPatternMatching<'a, 'p>: Iterator<Item = Quad<&'a Self::Resource>>
198 where
199 Self: 'a,
200 Self::Resource: 'p;
201
202 fn quad_pattern_matching<'p>(
205 &self,
206 pattern: CanonicalQuadPattern<&'p Self::Resource>,
207 ) -> Self::QuadPatternMatching<'_, 'p>;
208
209 fn contains_quad(&self, quad: Quad<&Self::Resource>) -> bool {
211 self.quad_pattern_matching(quad.into()).next().is_some()
212 }
213
214 fn contains_quad_subject(&self, subject: &Self::Resource) -> bool {
216 use crate::pattern::quad::canonical::{
217 GivenSubject, GivenSubjectAnyPredicate, GivenSubjectAnyPredicateAnyObject,
218 };
219 self.quad_pattern_matching(CanonicalQuadPattern::GivenSubject(
220 subject,
221 GivenSubject::AnyPredicate(GivenSubjectAnyPredicate::AnyObject(
222 GivenSubjectAnyPredicateAnyObject::AnyGraph,
223 )),
224 ))
225 .next()
226 .is_some()
227 }
228
229 fn contains_quad_predicate(&self, predicate: &Self::Resource) -> bool {
231 use crate::pattern::quad::canonical::{
232 AnySubject, AnySubjectGivenPredicate, AnySubjectGivenPredicateAnyObject,
233 };
234 self.quad_pattern_matching(CanonicalQuadPattern::AnySubject(
235 AnySubject::GivenPredicate(
236 predicate,
237 AnySubjectGivenPredicate::AnyObject(AnySubjectGivenPredicateAnyObject::AnyGraph),
238 ),
239 ))
240 .next()
241 .is_some()
242 }
243
244 fn contains_quad_object(&self, object: &Self::Resource) -> bool {
246 use crate::pattern::quad::canonical::{
247 AnySubject, AnySubjectAnyPredicate, AnySubjectAnyPredicateGivenObject,
248 };
249 self.quad_pattern_matching(CanonicalQuadPattern::AnySubject(AnySubject::AnyPredicate(
250 AnySubjectAnyPredicate::GivenObject(
251 object,
252 AnySubjectAnyPredicateGivenObject::AnyGraph,
253 ),
254 )))
255 .next()
256 .is_some()
257 }
258
259 fn contains_named_graph(&self, named_graph: &Self::Resource) -> bool {
261 use crate::pattern::quad::canonical::{
262 AnySubject, AnySubjectAnyPredicate, AnySubjectAnyPredicateAnyObject,
263 };
264 self.quad_pattern_matching(CanonicalQuadPattern::AnySubject(AnySubject::AnyPredicate(
265 AnySubjectAnyPredicate::AnyObject(AnySubjectAnyPredicateAnyObject::GivenGraph(Some(
266 named_graph,
267 ))),
268 )))
269 .next()
270 .is_some()
271 }
272
273 fn quad_predicates_objects<'p>(
276 &self,
277 graph: Option<&'p Self::Resource>,
278 subject: &'p Self::Resource,
279 ) -> QuadPredicatesObjects<'_, 'p, Self>
280 where
281 Self: PredicateTraversableDataset,
282 {
283 QuadPredicatesObjects {
284 graph,
285 subject,
286 predicates: self.predicates(),
287 dataset: self,
288 }
289 }
290
291 fn quad_objects<'p>(
293 &self,
294 graph: Option<&'p Self::Resource>,
295 subject: &'p Self::Resource,
296 predicate: &'p Self::Resource,
297 ) -> QuadObjects<'_, 'p, Self> {
298 QuadObjects {
299 first: None,
300 inner: self.quad_pattern_matching(CanonicalQuadPattern::from_option_quad(Quad(
301 Some(subject),
302 Some(predicate),
303 None,
304 Some(graph),
305 ))),
306 }
307 }
308}
309
310impl<G: PatternMatchingGraph> PatternMatchingDataset for G {
311 type QuadPatternMatching<'a, 'p>
312 = OptionIterator<TripleToQuadIterator<G::TriplePatternMatching<'a, 'p>, &'a G::Resource>>
313 where
314 Self: 'a,
315 Self::Resource: 'p;
316
317 fn quad_pattern_matching<'p>(
318 &self,
319 pattern: CanonicalQuadPattern<&'p Self::Resource>,
320 ) -> Self::QuadPatternMatching<'_, 'p> {
321 let (pattern, g) = pattern.into_triple();
322 match g {
323 PatternGraph::Given(None) | PatternGraph::Any => OptionIterator(Some(
324 TripleToQuadIterator::new(self.triple_pattern_matching(pattern)),
325 )),
326 _ => OptionIterator(None),
327 }
328 }
329}
330
331pub struct QuadPredicatesObjects<
332 'a,
333 'p,
334 D: 'a + ?Sized + PredicateTraversableDataset + PatternMatchingDataset,
335> {
336 graph: Option<&'p D::Resource>,
337 subject: &'p D::Resource,
338 predicates: D::Predicates<'a>,
339 dataset: &'a D,
340}
341
342impl<'a: 'p, 'p, D: 'a + ?Sized + PredicateTraversableDataset + PatternMatchingDataset> Iterator
343 for QuadPredicatesObjects<'a, 'p, D>
344where
345 D::Resource: 'p,
346{
347 type Item = (&'a D::Resource, QuadObjects<'p, 'p, D>);
348
349 fn next(&mut self) -> Option<Self::Item> {
350 for predicate in &mut self.predicates {
351 use crate::pattern::quad::canonical::{
352 GivenSubject, GivenSubjectGivenPredicate, GivenSubjectGivenPredicateAnyObject,
353 };
354 let pattern = CanonicalQuadPattern::GivenSubject(
355 self.subject,
356 GivenSubject::GivenPredicate(
357 predicate,
358 GivenSubjectGivenPredicate::AnyObject(
359 GivenSubjectGivenPredicateAnyObject::GivenGraph(self.graph),
360 ),
361 ),
362 );
363
364 let mut iter = self.dataset.quad_pattern_matching(pattern);
365 if let Some(Quad(_, _, o, _)) = iter.next() {
366 return Some((
367 predicate,
368 QuadObjects {
369 first: Some(o),
370 inner: iter,
371 },
372 ));
373 }
374 }
375
376 None
377 }
378}
379
380pub struct QuadObjects<'a, 'p, D: 'a + ?Sized + PatternMatchingDataset>
381where
382 D::Resource: 'p,
383{
384 first: Option<&'a D::Resource>,
385 inner: D::QuadPatternMatching<'a, 'p>,
386}
387
388impl<'a, 'p, D: 'a + ?Sized + PatternMatchingDataset> Iterator for QuadObjects<'a, 'p, D>
389where
390 D::Resource: 'p,
391{
392 type Item = &'a D::Resource;
393
394 fn next(&mut self) -> Option<Self::Item> {
395 self.first
396 .take()
397 .or_else(|| self.inner.next().map(Quad::into_object))
398 }
399}
400
401pub trait DatasetMut: Dataset {
403 fn insert(&mut self, quad: Quad<Self::Resource>);
405
406 fn remove(&mut self, quad: Quad<&Self::Resource>);
408}
409
410pub struct DatasetView<'a, D: Dataset> {
412 pub dataset: &'a D,
413 pub graph: Option<&'a D::Resource>,
414}
415
416pub struct DatasetGraphView<'a, D: Dataset> {
418 pub dataset: &'a D,
419 pub graph: Option<&'a D::Resource>,
420 pub resource: &'a D::Resource,
421}