1use crate::utils::BTreeBijection;
3use crate::{Quad, Triple, View};
4use educe::Educe;
5use rdf_types::{AsRdfTerm, FromBlankId, IntoBlankId, MaybeBlankId};
6use std::borrow::Borrow;
7use std::collections::{BTreeMap, BTreeSet};
8use std::fmt;
9use std::hash::Hash;
10
11mod graph;
12
13pub use graph::*;
14
15#[derive(Educe, Clone)]
16#[educe(PartialEq(bound = "S: Ord, P: Ord, O: Ord, G: Ord"))]
17#[educe(Eq(bound = "S: Ord, P: Ord, O: Ord, G: Ord"))]
18#[educe(Ord(bound = "S: Ord, P: Ord, O: Ord, G: Ord"))]
19#[educe(Hash(bound = "S: Ord + Hash, P: Ord + Hash, O: Ord + Hash, G: Ord + Hash"))]
20#[educe(Default)]
21pub struct BTreeDataset<S = rdf_types::Term, P = S, O = S, G = S> {
22 default: BTreeGraph<S, P, O>,
23 named: BTreeMap<G, BTreeGraph<S, P, O>>,
24}
25
26impl<S: Ord, P: Ord, O: Ord, G: Ord> PartialOrd for BTreeDataset<S, P, O, G> {
27 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
28 Some(self.cmp(other))
29 }
30}
31
32impl<S, P, O, G> BTreeDataset<S, P, O, G> {
33 pub fn new() -> Self {
34 Self::default()
35 }
36
37 #[inline(always)]
39 pub fn is_empty(&self) -> bool {
40 self.default.is_empty() && self.named.iter().all(|(_, g)| g.is_empty())
41 }
42
43 #[inline(always)]
45 pub fn len(&self) -> usize {
46 self.named
47 .iter()
48 .fold(self.default.len(), |x, (_, g)| g.len() + x)
49 }
50
51 pub fn graph<W>(&self, id: Option<&W>) -> Option<&BTreeGraph<S, P, O>>
52 where
53 G: Borrow<W> + Ord,
54 W: ?Sized + Ord,
55 {
56 match id {
57 Some(id) => self.named.get(id),
58 None => Some(&self.default),
59 }
60 }
61
62 #[allow(clippy::type_complexity)]
63 pub fn graph_entry<W>(&self, id: Option<&W>) -> Option<(Option<&G>, &BTreeGraph<S, P, O>)>
64 where
65 G: Borrow<W> + Ord,
66 W: ?Sized + Ord,
67 {
68 match id {
69 Some(id) => self.named.get_key_value(id).map(|(k, v)| (Some(k), v)),
70 None => Some((None, &self.default)),
71 }
72 }
73
74 pub fn graphs(&self) -> Graphs<'_, S, P, O, G> {
75 Graphs {
76 default: Some(&self.default),
77 it: self.named.iter(),
78 }
79 }
80
81 pub fn quads(&self) -> Quads<'_, S, P, O, G> {
82 Quads {
83 graphs: self.graphs(),
84 graph: None,
85 triples: None,
86 }
87 }
88
89 pub fn graph_mut<W: ?Sized + Ord>(&mut self, id: Option<&W>) -> Option<&mut BTreeGraph<S, P, O>>
90 where
91 G: Ord + Borrow<W>,
92 {
93 match id {
94 Some(id) => self.named.get_mut(id),
95 None => Some(&mut self.default),
96 }
97 }
98
99 pub fn graphs_mut(&mut self) -> GraphsMut<S, P, O, G> {
100 GraphsMut {
101 default: Some(&mut self.default),
102 it: self.named.iter_mut(),
103 }
104 }
105
106 pub fn insert_graph(&mut self, id: G, graph: BTreeGraph<S, P, O>) -> Option<BTreeGraph<S, P, O>>
107 where
108 G: Ord,
109 {
110 self.named.insert(id, graph)
111 }
112
113 pub fn into_graph(mut self, id: Option<&G>) -> Option<BTreeGraph<S, P, O>>
114 where
115 G: Ord,
116 {
117 match id {
118 Some(id) => self.named.remove(id),
119 None => Some(self.default),
120 }
121 }
122
123 pub fn into_graphs(self) -> IntoGraphs<S, P, O, G> {
124 IntoGraphs {
125 default: Some(self.default),
126 it: self.named.into_iter(),
127 }
128 }
129
130 pub fn into_quads(self) -> IntoQuads<S, P, O, G> {
131 IntoQuads {
132 graphs: self.into_graphs(),
133 graph: None,
134 triples: None,
135 }
136 }
137}
138
139impl<S: Ord, P: Ord, O: Ord, G: Ord> BTreeDataset<S, P, O, G> {
140 pub fn insert(&mut self, quad: Quad<S, P, O, G>) -> bool {
141 let (subject, predicate, object, graph_name) = quad.into_parts();
142 match self.graph_mut(graph_name.as_ref()) {
143 Some(g) => g.insert(Triple(subject, predicate, object)),
144 None => {
145 let mut g = BTreeGraph::new();
146 g.insert(Triple(subject, predicate, object));
147 self.insert_graph(graph_name.unwrap(), g);
148 true
149 }
150 }
151 }
152
153 pub fn remove<T: ?Sized + Ord, U: ?Sized + Ord, V: ?Sized + Ord, W: ?Sized + Ord>(
154 &mut self,
155 Quad(s, p, o, g): Quad<&T, &U, &V, &W>,
156 ) where
157 S: Borrow<T>,
158 P: Borrow<U>,
159 O: Borrow<V>,
160 G: Borrow<W>,
161 {
162 if let Some(graph) = self.graph_mut(g) {
163 graph.remove(Triple(s, p, o))
164 }
165 }
166
167 pub fn remove_graph<W: ?Sized + Ord>(&mut self, g: &W) -> Option<BTreeGraph<S, P, O>>
168 where
169 G: Borrow<W>,
170 {
171 self.named.remove(g)
172 }
173
174 pub fn take<T: ?Sized + Ord, U: ?Sized + Ord, V: ?Sized + Ord, W: ?Sized + Ord>(
175 &mut self,
176 Quad(s, p, o, g): Quad<&T, &U, &V, &W>,
177 ) -> Option<Quad<S, P, O, G>>
178 where
179 S: Clone + Borrow<T>,
180 P: Clone + Borrow<U>,
181 O: Borrow<V>,
182 G: Clone + Borrow<W>,
183 {
184 let graph = self.graph_mut(g)?;
185 let Triple(s, p, o) = graph.take(Triple(s, p, o))?;
186
187 let is_graph_empty = graph.is_empty();
188 let g = g.map(|g| {
189 if is_graph_empty {
190 self.named.remove_entry(g).unwrap().0
191 } else {
192 self.named.get_key_value(g).unwrap().0.clone()
193 }
194 });
195
196 Some(Quad(s, p, o, g))
197 }
198
199 pub fn take_match<T: ?Sized + Ord, U: ?Sized + Ord, V: ?Sized + Ord, W: ?Sized + Ord>(
200 &mut self,
201 Quad(s, p, o, g): Quad<Option<&T>, Option<&U>, Option<&V>, Option<&W>>,
202 ) -> Option<Quad<S, P, O, G>>
203 where
204 S: Clone + Borrow<T>,
205 P: Clone + Borrow<U>,
206 O: Borrow<V>,
207 G: Clone + Borrow<W>,
208 {
209 match g {
210 Some(g) => {
211 let graph = self.graph_mut(g)?;
212 let Triple(s, p, o) = graph.take_match(Triple(s, p, o))?;
213
214 let is_graph_empty = graph.is_empty();
215 let g = g.map(|g| {
216 if is_graph_empty {
217 self.named.remove_entry(g).unwrap().0
218 } else {
219 self.named.get_key_value(g).unwrap().0.clone()
220 }
221 });
222
223 Some(Quad(s, p, o, g))
224 }
225 None => {
226 for (g, graph) in self.graphs_mut() {
227 if let Some(Triple(s, p, o)) = graph.take_match(Triple(s, p, o)) {
228 return Some(Quad(s, p, o, g.cloned()));
229 }
230 }
231
232 None
233 }
234 }
235 }
236
237 pub fn absorb<D: crate::SizedDataset<Subject = S, Predicate = P, Object = O, GraphLabel = G>>(
238 &mut self,
239 other: D,
240 ) where
241 D::Graph: crate::SizedGraph,
242 {
243 for (id, graph) in other.into_graphs() {
244 match self.graph_mut(id.as_ref()) {
245 Some(g) => g.absorb(graph),
246 None => {
247 self.insert_graph(id.unwrap(), BTreeGraph::from_graph(graph));
248 }
249 }
250 }
251 }
252
253 pub fn substitute_blank_ids<B>(self, f: impl Fn(B) -> B) -> Self
255 where
256 S: Clone + MaybeBlankId<BlankId = B> + IntoBlankId + FromBlankId,
257 P: Clone + MaybeBlankId<BlankId = B> + IntoBlankId + FromBlankId,
258 O: MaybeBlankId<BlankId = B> + IntoBlankId + FromBlankId,
259 G: Clone + MaybeBlankId<BlankId = B> + IntoBlankId + FromBlankId,
260 {
261 let mut result = Self::new();
262
263 fn substitute_term<T: IntoBlankId + FromBlankId>(
264 term: T,
265 f: impl Fn(T::BlankId) -> T::BlankId,
266 ) -> T {
267 match term.try_into_blank() {
268 Ok(b) => T::from_blank(f(b)),
269 Err(term) => term,
270 }
271 }
272
273 fn substitute_quad<B, S, P, O, G>(
274 Quad(s, p, o, g): Quad<S, P, O, G>,
275 f: impl Fn(B) -> B,
276 ) -> Quad<S, P, O, G>
277 where
278 S: MaybeBlankId<BlankId = B> + IntoBlankId + FromBlankId,
279 P: MaybeBlankId<BlankId = B> + IntoBlankId + FromBlankId,
280 O: MaybeBlankId<BlankId = B> + IntoBlankId + FromBlankId,
281 G: MaybeBlankId<BlankId = B> + IntoBlankId + FromBlankId,
282 {
283 Quad(
284 substitute_term(s, &f),
285 substitute_term(p, &f),
286 substitute_term(o, &f),
287 g.map(|g| substitute_term(g, f)),
288 )
289 }
290
291 for quad in self.into_quads() {
292 result.insert(substitute_quad(quad, &f));
293 }
294
295 result
296 }
297
298 pub fn view<'a, A>(
299 &'a self,
300 graph_label: Option<&'a G>,
301 subject: &'a S,
302 access: A,
303 ) -> View<'a, Self, A> {
304 crate::Dataset::view(self, graph_label, subject, access)
305 }
306}
307
308impl<S: Ord, P: Ord, O: Ord, G: Ord> BTreeDataset<S, P, O, G> {
309 pub fn is_isomorphic_to<I, B, L>(&self, other: &Self) -> bool
315 where
316 S: AsRdfTerm<I, B, L>,
317 P: AsRdfTerm<I, B, L>,
318 O: AsRdfTerm<I, B, L>,
319 G: AsRdfTerm<I, B, L>,
320 I: PartialEq,
321 L: PartialEq,
322 B: Ord,
323 {
324 self.find_blank_id_bijection(other).is_some()
325 }
326
327 pub fn find_blank_id_bijection<'u, 'v, I: 'u + 'v, B, L: 'u + 'v>(
331 &'u self,
332 other: &'v Self,
333 ) -> Option<BTreeBijection<'u, 'v, B, B>>
334 where
335 S: AsRdfTerm<I, B, L>,
336 P: AsRdfTerm<I, B, L>,
337 O: AsRdfTerm<I, B, L>,
338 G: AsRdfTerm<I, B, L>,
339 I: PartialEq,
340 L: PartialEq,
341 B: Ord,
342 {
343 use crate::utils::isomorphism::btree::FindBTreeBlankIdBijection;
344
345 fn has_no_blank<I, B, L, S, P, O, G>(Quad(s, p, o, g): &Quad<&S, &P, &O, &G>) -> bool
346 where
347 S: AsRdfTerm<I, B, L>,
348 P: AsRdfTerm<I, B, L>,
349 O: AsRdfTerm<I, B, L>,
350 G: AsRdfTerm<I, B, L>,
351 {
352 !s.as_rdf_term().is_blank()
353 && !p.as_rdf_term().is_blank()
354 && !o.as_rdf_term().is_blank()
355 && !g.map(|g| g.as_rdf_term().is_blank()).unwrap_or(false)
356 }
357
358 let a_non_blank: BTreeSet<_> = self.quads().filter(has_no_blank).collect();
359 let b_non_blank: BTreeSet<_> = other.quads().filter(has_no_blank).collect();
360
361 if a_non_blank == b_non_blank {
362 Self::find_btree_blank_id_bijection(self, other)
363 } else {
364 None
365 }
366 }
367}
368
369impl<S: Ord, P: Ord, O: Ord, G: Ord> crate::Dataset for BTreeDataset<S, P, O, G> {
370 type Subject = S;
371 type Predicate = P;
372 type Object = O;
373 type GraphLabel = G;
374
375 type Graph = BTreeGraph<S, P, O>;
376 type Graphs<'a>
377 = Graphs<'a, S, P, O, G> where
378 Self: 'a,
379 S: 'a,
380 P: 'a,
381 O: 'a,
382 G: 'a,;
383 type Quads<'a>
384 = Quads<'a, S, P, O, G> where
385 Self: 'a,
386 S: 'a,
387 P: 'a,
388 O: 'a,;
389
390 type PatternMatching<'a, 'p> = PatternMatching<'a, 'p, S, P, O, G> where Self: 'a,
391 S: 'a + 'p,
392 P: 'a + 'p,
393 O: 'a + 'p,
394 G: 'a + 'p;
395
396 fn graph(&self, id: Option<&G>) -> Option<&BTreeGraph<S, P, O>> {
397 self.graph(id)
398 }
399
400 fn graphs(&self) -> Graphs<'_, S, P, O, G> {
401 self.graphs()
402 }
403
404 fn quads(&self) -> Quads<'_, S, P, O, G> {
405 self.quads()
406 }
407
408 fn pattern_matching<'p>(
409 &self,
410 Quad(s, p, o, g): Quad<
411 Option<&'p Self::Subject>,
412 Option<&'p Self::Predicate>,
413 Option<&'p Self::Object>,
414 Option<&'p Self::GraphLabel>,
415 >,
416 ) -> Self::PatternMatching<'_, 'p> {
417 let pattern = Triple(s, p, o);
418
419 match g {
420 Some(g) => PatternMatching {
421 pattern,
422 graphs: None,
423 current_graph: self
424 .graph_entry(g)
425 .map(|(g, graph)| (g, GraphPatternMatching::new(graph, pattern))),
426 },
427 None => PatternMatching {
428 pattern,
429 graphs: Some(self.graphs()),
430 current_graph: None,
431 },
432 }
433 }
434}
435
436impl<S: Ord, P: Ord, O: Ord, G: Ord> BTreeDataset<S, P, O, G> {
437 crate::macros::reflect_dataset_impl!();
438}
439
440impl<S: fmt::Debug, P: fmt::Debug, O: fmt::Debug, G: fmt::Debug> fmt::Debug
441 for BTreeDataset<S, P, O, G>
442{
443 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
444 write!(f, "{{")?;
445
446 for (i, rdf_types::Quad(s, p, o, g)) in self.quads().enumerate() {
447 if i > 0 {
448 write!(f, ",")?;
449 }
450
451 match g {
452 Some(g) => write!(f, " {s:?} {p:?} {o:?} {g:?}")?,
453 None => write!(f, " {s:?} {p:?} {o:?}")?,
454 }
455 }
456
457 write!(f, " }}")
458 }
459}
460
461#[allow(clippy::type_complexity)]
462pub struct PatternMatching<'a, 'p, S, P, O, G> {
463 pattern: Triple<Option<&'p S>, Option<&'p P>, Option<&'p O>>,
464 graphs: Option<Graphs<'a, S, P, O, G>>,
465 current_graph: Option<(Option<&'a G>, GraphPatternMatching<'a, 'p, S, P, O>)>,
466}
467
468impl<'a, 'p, S: Ord, P: Ord, O: Ord, G: Ord> Iterator for PatternMatching<'a, 'p, S, P, O, G> {
469 type Item = Quad<&'a S, &'a P, &'a O, &'a G>;
470
471 fn next(&mut self) -> Option<Self::Item> {
472 loop {
473 match &mut self.current_graph {
474 Some((g, m)) => match m.next() {
475 Some(Triple(s, p, o)) => break Some(Quad(s, p, o, *g)),
476 None => self.current_graph = None,
477 },
478 None => match &mut self.graphs {
479 Some(graphs) => match graphs.next() {
480 Some((g, graph)) => {
481 self.current_graph =
482 Some((g, GraphPatternMatching::new(graph, self.pattern)))
483 }
484 None => break None,
485 },
486 None => break None,
487 },
488 }
489 }
490 }
491}
492
493pub struct GraphPatternMatching<'a, 'p, S, P, O> {
494 predicate_pattern: Option<&'p P>,
495 object_pattern: Option<&'p O>,
496 subjects: Option<std::collections::btree_map::Iter<'a, S, BTreeMap<P, BTreeSet<O>>>>,
497 current_subject: Option<(&'a S, SubjectPatternMatching<'a, 'p, P, O>)>,
498}
499
500impl<'a, 'p, S: Ord, P: Ord, O: Ord> GraphPatternMatching<'a, 'p, S, P, O> {
501 fn new(
502 graph: &'a BTreeGraph<S, P, O>,
503 pattern: Triple<Option<&'p S>, Option<&'p P>, Option<&'p O>>,
504 ) -> Self {
505 match pattern.into_subject() {
506 Some(s) => Self {
507 predicate_pattern: pattern.into_predicate(),
508 object_pattern: pattern.into_object(),
509 subjects: None,
510 current_subject: graph.table.get_key_value(s).map(|(s, subject)| {
511 (
512 s,
513 SubjectPatternMatching::new(
514 subject,
515 pattern.into_predicate(),
516 pattern.into_object(),
517 ),
518 )
519 }),
520 },
521 None => Self {
522 predicate_pattern: pattern.into_predicate(),
523 object_pattern: pattern.into_object(),
524 subjects: Some(graph.table.iter()),
525 current_subject: None,
526 },
527 }
528 }
529}
530
531impl<'a, 'p, S: Ord, P: Ord, O: Ord> Iterator for GraphPatternMatching<'a, 'p, S, P, O> {
532 type Item = Triple<&'a S, &'a P, &'a O>;
533
534 fn next(&mut self) -> Option<Self::Item> {
535 loop {
536 match &mut self.current_subject {
537 Some((s, m)) => match m.next() {
538 Some((p, o)) => break Some(Triple(s, p, o)),
539 None => self.current_subject = None,
540 },
541 None => match &mut self.subjects {
542 Some(subjects) => match subjects.next() {
543 Some((s, subject)) => {
544 self.current_subject = Some((
545 s,
546 SubjectPatternMatching::new(
547 subject,
548 self.predicate_pattern,
549 self.object_pattern,
550 ),
551 ))
552 }
553 None => break None,
554 },
555 None => break None,
556 },
557 }
558 }
559 }
560}
561
562struct SubjectPatternMatching<'a, 'p, P, O> {
563 object_pattern: Option<&'p O>,
564 predicates: Option<std::collections::btree_map::Iter<'a, P, BTreeSet<O>>>,
565 current_predicate: Option<(&'a P, PredicatePatternMatching<'a, O>)>,
566}
567
568impl<'a, 'p, P: Ord, O: Ord> SubjectPatternMatching<'a, 'p, P, O> {
569 fn new(
570 subject: &'a BTreeMap<P, BTreeSet<O>>,
571 predicate_pattern: Option<&'p P>,
572 object_pattern: Option<&'p O>,
573 ) -> Self {
574 match predicate_pattern {
575 Some(p) => Self {
576 object_pattern,
577 predicates: None,
578 current_predicate: subject
579 .get_key_value(p)
580 .map(|(p, pred)| (p, PredicatePatternMatching::new(pred, object_pattern))),
581 },
582 None => Self {
583 object_pattern,
584 predicates: Some(subject.iter()),
585 current_predicate: None,
586 },
587 }
588 }
589}
590
591impl<'a, 'p, P: Ord, O: Ord> Iterator for SubjectPatternMatching<'a, 'p, P, O> {
592 type Item = (&'a P, &'a O);
593
594 fn next(&mut self) -> Option<Self::Item> {
595 loop {
596 match &mut self.current_predicate {
597 Some((p, m)) => match m.next() {
598 Some(o) => break Some((p, o)),
599 None => self.current_predicate = None,
600 },
601 None => match &mut self.predicates {
602 Some(predicates) => match predicates.next() {
603 Some((p, pred)) => {
604 self.current_predicate =
605 Some((p, PredicatePatternMatching::new(pred, self.object_pattern)))
606 }
607 None => break None,
608 },
609 None => break None,
610 },
611 }
612 }
613 }
614}
615
616enum PredicatePatternMatching<'a, O> {
617 One(Option<&'a O>),
618 Any(std::collections::btree_set::Iter<'a, O>),
619}
620
621impl<'a, O: Ord> PredicatePatternMatching<'a, O> {
622 fn new(predicate: &'a BTreeSet<O>, object_pattern: Option<&O>) -> Self {
623 match object_pattern {
624 Some(o) => Self::One(predicate.get(o)),
625 None => Self::Any(predicate.iter()),
626 }
627 }
628}
629
630impl<'a, O: Ord> Iterator for PredicatePatternMatching<'a, O> {
631 type Item = &'a O;
632
633 fn next(&mut self) -> Option<Self::Item> {
634 match self {
635 Self::One(o) => o.take(),
636 Self::Any(iter) => iter.next(),
637 }
638 }
639}
640
641#[derive(Educe)]
642#[educe(Clone)]
643pub struct Graphs<'a, S, P, O, G> {
644 default: Option<&'a BTreeGraph<S, P, O>>,
645 it: std::collections::btree_map::Iter<'a, G, BTreeGraph<S, P, O>>,
646}
647
648impl<'a, S, P, O, G> Iterator for Graphs<'a, S, P, O, G> {
649 type Item = (Option<&'a G>, &'a BTreeGraph<S, P, O>);
650
651 fn next(&mut self) -> Option<Self::Item> {
652 if let Some(default) = self.default {
653 self.default = None;
654 Some((None, default))
655 } else {
656 self.it.next().map(|(id, graph)| (Some(id), graph))
657 }
658 }
659}
660
661pub struct GraphsMut<'a, S, P, O, G> {
662 default: Option<&'a mut BTreeGraph<S, P, O>>,
663 it: std::collections::btree_map::IterMut<'a, G, BTreeGraph<S, P, O>>,
664}
665
666impl<'a, S, P, O, G> Iterator for GraphsMut<'a, S, P, O, G> {
667 type Item = (Option<&'a G>, &'a mut BTreeGraph<S, P, O>);
668
669 fn next(&mut self) -> Option<Self::Item> {
670 let mut default = None;
671 std::mem::swap(&mut default, &mut self.default);
672 if let Some(default) = default {
673 self.default = None;
674 Some((None, default))
675 } else {
676 self.it.next().map(|(id, graph)| (Some(id), graph))
677 }
678 }
679}
680
681#[derive(Educe)]
682#[educe(Clone)]
683pub struct Quads<'a, S, P, O, G> {
684 graphs: Graphs<'a, S, P, O, G>,
685 graph: Option<&'a G>,
686 triples: Option<Iter<'a, S, P, O>>,
687}
688
689impl<'a, S, P, O, G> Iterator for Quads<'a, S, P, O, G> {
690 type Item = Quad<&'a S, &'a P, &'a O, &'a G>;
691
692 fn next(&mut self) -> Option<Quad<&'a S, &'a P, &'a O, &'a G>> {
693 loop {
694 match &mut self.triples {
695 Some(triples) => match triples.next() {
696 Some(triple) => return Some(Quad(triple.0, triple.1, triple.2, self.graph)),
697 None => {
698 self.triples = None;
699 }
700 },
701 None => match self.graphs.next() {
702 Some((id, graph)) => {
703 self.graph = id;
704 self.triples = Some(graph.triples())
705 }
706 None => return None,
707 },
708 }
709 }
710 }
711}
712
713impl<S: Clone + Ord, P: Clone + Ord, O: Ord, G: Clone + Ord> crate::SizedDataset
714 for BTreeDataset<S, P, O, G>
715{
716 type IntoGraphs = IntoGraphs<S, P, O, G>;
717 type IntoQuads = IntoQuads<S, P, O, G>;
718
719 fn into_graph(self, id: Option<&G>) -> Option<Self::Graph> {
720 self.into_graph(id)
721 }
722
723 fn into_graphs(self) -> Self::IntoGraphs {
724 self.into_graphs()
725 }
726
727 fn into_quads(self) -> Self::IntoQuads {
728 self.into_quads()
729 }
730}
731
732impl<S: Clone + Ord, P: Clone + Ord, O: Ord, G: Clone + Ord> BTreeDataset<S, P, O, G> {
733 crate::macros::reflect_sized_dataset_impl!();
734}
735
736pub struct IntoGraphs<S, P, O, G> {
737 default: Option<BTreeGraph<S, P, O>>,
738 it: std::collections::btree_map::IntoIter<G, BTreeGraph<S, P, O>>,
739}
740
741impl<S, P, O, G> Iterator for IntoGraphs<S, P, O, G> {
742 type Item = (Option<G>, BTreeGraph<S, P, O>);
743
744 fn next(&mut self) -> Option<Self::Item> {
745 let mut default = None;
746 std::mem::swap(&mut default, &mut self.default);
747 if let Some(default) = default {
748 self.default = None;
749 Some((None, default))
750 } else {
751 self.it.next().map(|(id, graph)| (Some(id), graph))
752 }
753 }
754}
755
756pub struct IntoQuads<S = rdf_types::Term, P = S, O = S, G = S> {
757 graphs: IntoGraphs<S, P, O, G>,
758 graph: Option<G>,
759 triples: Option<IntoIter<S, P, O>>,
760}
761
762impl<S: Clone, P: Clone, O, G: Clone> Iterator for IntoQuads<S, P, O, G> {
763 type Item = Quad<S, P, O, G>;
764
765 fn next(&mut self) -> Option<Quad<S, P, O, G>> {
766 loop {
767 match &mut self.triples {
768 Some(triples) => match triples.next() {
769 Some(triple) => {
770 return Some(Quad(triple.0, triple.1, triple.2, self.graph.clone()))
771 }
772 None => {
773 self.triples = None;
774 }
775 },
776 None => match self.graphs.next() {
777 Some((id, graph)) => {
778 self.graph = id;
779 self.triples = Some(graph.into_triples())
780 }
781 None => return None,
782 },
783 }
784 }
785 }
786}
787
788impl<S: Ord, P: Ord, O: Ord, G: Ord> crate::MutableDataset for BTreeDataset<S, P, O, G> {
789 type GraphsMut<'a>
790 = GraphsMut<'a, S, P, O, G> where
791 Self: 'a,
792 S: 'a,
793 P: 'a,
794 O: 'a,
795 G: 'a,;
796
797 fn graph_mut(&mut self, id: Option<&G>) -> Option<&mut Self::Graph> {
798 self.graph_mut(id)
799 }
800
801 fn graphs_mut(&mut self) -> Self::GraphsMut<'_> {
802 self.graphs_mut()
803 }
804
805 fn insert_graph(&mut self, id: G, graph: Self::Graph) -> Option<Self::Graph> {
806 self.named.insert(id, graph)
807 }
808
809 fn insert(&mut self, quad: Quad<S, P, O, G>) -> bool {
810 self.insert(quad)
811 }
812
813 fn remove(&mut self, quad: Quad<&S, &P, &O, &G>) {
814 self.remove(quad)
815 }
816
817 fn absorb<D: crate::SizedDataset<Subject = S, Predicate = P, Object = O, GraphLabel = G>>(
818 &mut self,
819 other: D,
820 ) where
821 D::Graph: crate::SizedGraph,
822 {
823 self.absorb(other)
824 }
825}
826
827impl<S: Ord, P: Ord, O: Ord, G: Ord> BTreeDataset<S, P, O, G> {
828 crate::macros::reflect_mutable_dataset_impl!();
829}
830
831impl<
832 S: Clone + Borrow<T> + Ord,
833 P: Clone + Borrow<U> + Ord,
834 O: Borrow<V> + Ord,
835 G: Clone + Borrow<W> + Ord,
836 T: ?Sized + Ord,
837 U: ?Sized + Ord,
838 V: ?Sized + Ord,
839 W: ?Sized + Ord,
840 > crate::DatasetTake<T, U, V, W> for BTreeDataset<S, P, O, G>
841{
842 fn take(
843 &mut self,
844 quad: Quad<&T, &U, &V, &W>,
845 ) -> Option<Quad<Self::Subject, Self::Predicate, Self::Object, Self::GraphLabel>> {
846 self.take(quad)
847 }
848
849 fn take_match(
850 &mut self,
851 quad: Quad<Option<&T>, Option<&U>, Option<&V>, Option<&W>>,
852 ) -> Option<Quad<Self::Subject, Self::Predicate, Self::Object, Self::GraphLabel>> {
853 self.take_match(quad)
854 }
855}
856
857impl<'a, S, P, O, G> IntoIterator for &'a BTreeDataset<S, P, O, G> {
858 type Item = Quad<&'a S, &'a P, &'a O, &'a G>;
859 type IntoIter = Quads<'a, S, P, O, G>;
860
861 fn into_iter(self) -> Self::IntoIter {
862 self.quads()
863 }
864}
865
866impl<S: Clone, P: Clone, O, G: Clone> IntoIterator for BTreeDataset<S, P, O, G> {
867 type Item = Quad<S, P, O, G>;
868 type IntoIter = IntoQuads<S, P, O, G>;
869
870 fn into_iter(self) -> Self::IntoIter {
871 self.into_quads()
872 }
873}
874
875impl<S: Ord, P: Ord, O: Ord, G: Ord> std::iter::FromIterator<Quad<S, P, O, G>>
876 for BTreeDataset<S, P, O, G>
877{
878 fn from_iter<I: IntoIterator<Item = Quad<S, P, O, G>>>(iter: I) -> Self {
879 let mut ds = Self::new();
880 ds.extend(iter);
881 ds
882 }
883}
884
885impl<S: Ord, P: Ord, O: Ord, G: Ord> std::iter::Extend<Quad<S, P, O, G>>
886 for BTreeDataset<S, P, O, G>
887{
888 fn extend<I: IntoIterator<Item = Quad<S, P, O, G>>>(&mut self, iter: I) {
889 for quad in iter {
890 self.insert(quad);
891 }
892 }
893}
894
895#[cfg(feature = "serde")]
896impl<S, P, O, G> serde::Serialize for BTreeDataset<S, P, O, G>
897where
898 S: serde::Serialize,
899 P: serde::Serialize,
900 O: serde::Serialize,
901 G: serde::Serialize,
902{
903 fn serialize<E>(&self, serializer: E) -> Result<E::Ok, E::Error>
904 where
905 E: serde::Serializer,
906 {
907 use serde::ser::SerializeSeq;
908 let mut seq = serializer.serialize_seq(Some(self.len()))?;
909
910 for quad in self.quads() {
911 seq.serialize_element(&quad)?
912 }
913
914 seq.end()
915 }
916}
917
918#[cfg(feature = "serde")]
919impl<'de, S, P, O, G> serde::Deserialize<'de> for BTreeDataset<S, P, O, G>
920where
921 S: Ord + serde::Deserialize<'de>,
922 P: Ord + serde::Deserialize<'de>,
923 O: Ord + serde::Deserialize<'de>,
924 G: Ord + serde::Deserialize<'de>,
925{
926 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
927 where
928 D: serde::Deserializer<'de>,
929 {
930 pub struct Visitor<S, P, O, G>(std::marker::PhantomData<(S, P, O, G)>);
931
932 impl<'de, S, P, O, G> serde::de::Visitor<'de> for Visitor<S, P, O, G>
933 where
934 S: Ord + serde::Deserialize<'de>,
935 P: Ord + serde::Deserialize<'de>,
936 O: Ord + serde::Deserialize<'de>,
937 G: Ord + serde::Deserialize<'de>,
938 {
939 type Value = BTreeDataset<S, P, O, G>;
940
941 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
942 write!(formatter, "an RDF dataset")
943 }
944
945 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
946 where
947 A: serde::de::SeqAccess<'de>,
948 {
949 let mut result = BTreeDataset::new();
950
951 while let Some(quad) = seq.next_element()? {
952 result.insert(quad);
953 }
954
955 Ok(result)
956 }
957 }
958
959 deserializer.deserialize_seq(Visitor(std::marker::PhantomData))
960 }
961}