sophia_api/dataset/
_foreign_impl.rs

1use super::*;
2use crate::quad::{Gspo, QBorrowTerm, Spog};
3use crate::source::SourceError;
4use crate::term::FromTerm;
5use std::collections::{BTreeSet, HashSet};
6use std::convert::Infallible;
7use std::hash::{BuildHasher, Hash};
8
9//
10// foreign implementations
11//
12
13// reference to Dataset
14
15impl<'a, T: Dataset + ?Sized> Dataset for &'a T {
16    type Quad<'x> = T::Quad<'x> where Self: 'x;
17
18    type Error = T::Error;
19
20    fn quads(&self) -> DQuadSource<Self> {
21        T::quads(*self)
22    }
23
24    fn quads_matching<'s, S, P, O, G>(&'s self, sm: S, pm: P, om: O, gm: G) -> DQuadSource<'s, Self>
25    where
26        S: TermMatcher + 's,
27        P: TermMatcher + 's,
28        O: TermMatcher + 's,
29        G: GraphNameMatcher + 's,
30    {
31        T::quads_matching(*self, sm, pm, om, gm)
32    }
33
34    fn contains<TS, TP, TO, TG>(&self, s: TS, p: TP, o: TO, g: GraphName<TG>) -> DResult<Self, bool>
35    where
36        TS: Term,
37        TP: Term,
38        TO: Term,
39        TG: Term,
40    {
41        T::contains(*self, s, p, o, g)
42    }
43
44    fn subjects(&self) -> DTermSource<Self> {
45        T::subjects(*self)
46    }
47
48    fn predicates(&self) -> DTermSource<Self> {
49        T::predicates(*self)
50    }
51
52    fn objects(&self) -> DTermSource<Self> {
53        T::objects(*self)
54    }
55
56    fn graph_names(&self) -> DTermSource<Self> {
57        T::graph_names(*self)
58    }
59
60    fn iris(&self) -> DTermSource<Self> {
61        T::iris(*self)
62    }
63
64    fn blank_nodes(&self) -> DTermSource<Self> {
65        T::blank_nodes(*self)
66    }
67
68    fn literals(&self) -> DTermSource<Self> {
69        T::literals(*self)
70    }
71
72    fn quoted_triples<'s>(&'s self) -> DTermSource<'s, Self>
73    where
74        DTerm<'s, Self>: Clone,
75    {
76        T::quoted_triples(*self)
77    }
78
79    fn variables(&self) -> DTermSource<Self> {
80        T::variables(*self)
81    }
82}
83
84// NB: this one is required so that &'a mut T can also implement MutableDataset
85impl<'a, T: Dataset + ?Sized> Dataset for &'a mut T {
86    type Quad<'x> = T::Quad<'x> where Self: 'x;
87
88    type Error = T::Error;
89
90    fn quads(&self) -> DQuadSource<Self> {
91        T::quads(*self)
92    }
93
94    fn quads_matching<'s, S, P, O, G>(&'s self, sm: S, pm: P, om: O, gm: G) -> DQuadSource<'s, Self>
95    where
96        S: TermMatcher + 's,
97        P: TermMatcher + 's,
98        O: TermMatcher + 's,
99        G: GraphNameMatcher + 's,
100    {
101        T::quads_matching(*self, sm, pm, om, gm)
102    }
103
104    fn contains<TS, TP, TO, TG>(&self, s: TS, p: TP, o: TO, g: GraphName<TG>) -> DResult<Self, bool>
105    where
106        TS: Term,
107        TP: Term,
108        TO: Term,
109        TG: Term,
110    {
111        T::contains(*self, s, p, o, g)
112    }
113
114    fn subjects(&self) -> DTermSource<Self> {
115        T::subjects(*self)
116    }
117
118    fn predicates(&self) -> DTermSource<Self> {
119        T::predicates(*self)
120    }
121
122    fn objects(&self) -> DTermSource<Self> {
123        T::objects(*self)
124    }
125
126    fn graph_names(&self) -> DTermSource<Self> {
127        T::graph_names(*self)
128    }
129
130    fn iris(&self) -> DTermSource<Self> {
131        T::iris(*self)
132    }
133
134    fn blank_nodes(&self) -> DTermSource<Self> {
135        T::blank_nodes(*self)
136    }
137
138    fn literals(&self) -> DTermSource<Self> {
139        T::literals(*self)
140    }
141
142    fn quoted_triples<'s>(&'s self) -> DTermSource<'s, Self>
143    where
144        DTerm<'s, Self>: Clone,
145    {
146        T::quoted_triples(*self)
147    }
148
149    fn variables(&self) -> DTermSource<Self> {
150        T::variables(*self)
151    }
152}
153
154impl<T: MutableDataset + ?Sized> MutableDataset for &mut T {
155    type MutationError = T::MutationError;
156
157    fn insert<TS, TP, TO, TG>(
158        &mut self,
159        s: TS,
160        p: TP,
161        o: TO,
162        g: GraphName<TG>,
163    ) -> MdResult<Self, bool>
164    where
165        TS: Term,
166        TP: Term,
167        TO: Term,
168        TG: Term,
169    {
170        T::insert(*self, s, p, o, g)
171    }
172
173    fn remove<TS, TP, TO, TG>(
174        &mut self,
175        s: TS,
176        p: TP,
177        o: TO,
178        g: GraphName<TG>,
179    ) -> MdResult<Self, bool>
180    where
181        TS: Term,
182        TP: Term,
183        TO: Term,
184        TG: Term,
185    {
186        T::remove(*self, s, p, o, g)
187    }
188
189    fn insert_all<TS: QuadSource>(
190        &mut self,
191        src: TS,
192    ) -> StreamResult<usize, TS::Error, Self::MutationError> {
193        T::insert_all(*self, src)
194    }
195
196    fn remove_all<TS: QuadSource>(
197        &mut self,
198        src: TS,
199    ) -> StreamResult<usize, TS::Error, Self::MutationError> {
200        T::remove_all(*self, src)
201    }
202
203    fn remove_matching<S, P, O, G>(
204        &mut self,
205        ms: S,
206        mp: P,
207        mo: O,
208        mg: G,
209    ) -> Result<usize, Self::MutationError>
210    where
211        S: TermMatcher,
212        P: TermMatcher,
213        O: TermMatcher,
214        G: GraphNameMatcher,
215        Self::MutationError: From<Self::Error>,
216    {
217        T::remove_matching(*self, ms, mp, mo, mg)
218    }
219
220    fn retain_matching<S, P, O, G>(
221        &mut self,
222        ms: S,
223        mp: P,
224        mo: O,
225        mg: G,
226    ) -> Result<(), Self::MutationError>
227    where
228        S: TermMatcher,
229        P: TermMatcher,
230        O: TermMatcher,
231        G: GraphNameMatcher,
232        Self::MutationError: From<Self::Error>,
233    {
234        T::retain_matching(*self, ms, mp, mo, mg)
235    }
236}
237
238//
239// foreign implementations
240//
241
242// slice of quads
243
244impl<Q: Quad> Dataset for [Q] {
245    type Error = Infallible;
246    type Quad<'x> = Spog<QBorrowTerm<'x, Q>> where Self: 'x;
247
248    fn quads(&self) -> DQuadSource<Self> {
249        Box::new(self.iter().map(Quad::spog).map(Ok))
250    }
251}
252
253// Vec of quads
254
255impl<Q: Quad> Dataset for Vec<Q> {
256    type Error = Infallible;
257    type Quad<'x> = Spog<QBorrowTerm<'x, Q>> where Self: 'x;
258
259    fn quads(&self) -> DQuadSource<Self> {
260        self[..].quads()
261    }
262}
263
264impl<T> CollectibleDataset for Vec<Spog<T>>
265where
266    T: Term + FromTerm,
267{
268    fn from_quad_source<TS: QuadSource>(
269        mut quads: TS,
270    ) -> StreamResult<Self, TS::Error, Self::Error> {
271        let min_cap = quads.size_hint_quads().0;
272        let mut v = Vec::with_capacity(min_cap);
273        quads
274            .for_each_quad(|q| {
275                v.push((
276                    [q.s().into_term(), q.p().into_term(), q.o().into_term()],
277                    q.g().map(Term::into_term),
278                ))
279            })
280            .map_err(SourceError)?;
281        Ok(v)
282    }
283}
284
285impl<T> MutableDataset for Vec<Spog<T>>
286where
287    T: Term + FromTerm,
288{
289    type MutationError = Infallible;
290
291    fn insert<TS, TP, TO, TG>(
292        &mut self,
293        s: TS,
294        p: TP,
295        o: TO,
296        g: GraphName<TG>,
297    ) -> MdResult<Self, bool>
298    where
299        TS: Term,
300        TP: Term,
301        TO: Term,
302        TG: Term,
303    {
304        self.push((
305            [s.into_term(), p.into_term(), o.into_term()],
306            g.map(Term::into_term),
307        ));
308        Ok(true)
309    }
310
311    fn remove<TS, TP, TO, TG>(
312        &mut self,
313        s: TS,
314        p: TP,
315        o: TO,
316        g: GraphName<TG>,
317    ) -> MdResult<Self, bool>
318    where
319        TS: Term,
320        TP: Term,
321        TO: Term,
322        TG: Term,
323    {
324        let s = s.borrow_term();
325        let p = p.borrow_term();
326        let o = o.borrow_term();
327        let g = g.as_ref().map(|gn| gn.borrow_term());
328        let mut i = 0;
329        while i < self.len() {
330            if self[i].matched_by([s], [p], [o], [g]) {
331                self.swap_remove(i);
332            } else {
333                i += 1;
334            }
335        }
336        Ok(true)
337    }
338}
339
340impl<T> CollectibleDataset for Vec<Gspo<T>>
341where
342    T: Term + FromTerm,
343{
344    fn from_quad_source<TS: QuadSource>(
345        mut quads: TS,
346    ) -> StreamResult<Self, TS::Error, Self::Error> {
347        let min_cap = quads.size_hint_quads().0;
348        let mut v = Vec::with_capacity(min_cap);
349        quads
350            .for_each_quad(|q| {
351                v.push((
352                    q.g().map(Term::into_term),
353                    [q.s().into_term(), q.p().into_term(), q.o().into_term()],
354                ))
355            })
356            .map_err(SourceError)?;
357        Ok(v)
358    }
359}
360
361impl<T> MutableDataset for Vec<Gspo<T>>
362where
363    T: Term + FromTerm,
364{
365    type MutationError = Infallible;
366
367    fn insert<TS, TP, TO, TG>(
368        &mut self,
369        s: TS,
370        p: TP,
371        o: TO,
372        g: GraphName<TG>,
373    ) -> MdResult<Self, bool>
374    where
375        TS: Term,
376        TP: Term,
377        TO: Term,
378        TG: Term,
379    {
380        self.push((
381            g.map(Term::into_term),
382            [s.into_term(), p.into_term(), o.into_term()],
383        ));
384        Ok(true)
385    }
386
387    fn remove<TS, TP, TO, TG>(
388        &mut self,
389        s: TS,
390        p: TP,
391        o: TO,
392        g: GraphName<TG>,
393    ) -> MdResult<Self, bool>
394    where
395        TS: Term,
396        TP: Term,
397        TO: Term,
398        TG: Term,
399    {
400        let s = s.borrow_term();
401        let p = p.borrow_term();
402        let o = o.borrow_term();
403        let g = g.as_ref().map(|gn| gn.borrow_term());
404        match self.iter().position(|q| q.matched_by([s], [p], [o], [g])) {
405            None => Ok(false),
406            Some(i) => {
407                self.swap_remove(i);
408                Ok(true)
409            }
410        }
411    }
412}
413
414// HashSet of quads
415
416impl<Q: Quad, S> Dataset for HashSet<Q, S> {
417    type Error = Infallible;
418    type Quad<'x> = Spog<QBorrowTerm<'x, Q>> where Self: 'x;
419
420    fn quads(&self) -> DQuadSource<Self> {
421        Box::new(self.iter().map(Quad::spog).map(Ok))
422    }
423}
424
425impl<T, S> CollectibleDataset for HashSet<Spog<T>, S>
426where
427    T: Term + Eq + FromTerm + Hash,
428    S: BuildHasher + Default,
429{
430    fn from_quad_source<TS: QuadSource>(
431        mut quads: TS,
432    ) -> StreamResult<Self, TS::Error, Self::Error> {
433        let min_cap = quads.size_hint_quads().0;
434        let mut s = HashSet::<_, S>::with_capacity_and_hasher(min_cap, S::default());
435        quads
436            .for_each_quad(|q| {
437                s.insert((
438                    [q.s().into_term(), q.p().into_term(), q.o().into_term()],
439                    q.g().map(Term::into_term),
440                ));
441            })
442            .map_err(SourceError)?;
443        Ok(s)
444    }
445}
446
447impl<T, S> MutableDataset for HashSet<Spog<T>, S>
448where
449    T: Term + Eq + FromTerm + Hash,
450    S: BuildHasher + Default,
451{
452    type MutationError = Infallible;
453
454    fn insert<TS, TP, TO, TG>(
455        &mut self,
456        s: TS,
457        p: TP,
458        o: TO,
459        g: GraphName<TG>,
460    ) -> MdResult<Self, bool>
461    where
462        TS: Term,
463        TP: Term,
464        TO: Term,
465        TG: Term,
466    {
467        Ok(self.insert((
468            [s.into_term(), p.into_term(), o.into_term()],
469            g.map(Term::into_term),
470        )))
471    }
472
473    fn remove<TS, TP, TO, TG>(
474        &mut self,
475        s: TS,
476        p: TP,
477        o: TO,
478        g: GraphName<TG>,
479    ) -> MdResult<Self, bool>
480    where
481        TS: Term,
482        TP: Term,
483        TO: Term,
484        TG: Term,
485    {
486        Ok(self.remove(&(
487            [s.into_term(), p.into_term(), o.into_term()],
488            g.map(Term::into_term),
489        )))
490    }
491}
492
493impl<T, S> CollectibleDataset for HashSet<Gspo<T>, S>
494where
495    T: Term + Eq + FromTerm + Hash,
496    S: BuildHasher + Default,
497{
498    fn from_quad_source<TS: QuadSource>(
499        mut quads: TS,
500    ) -> StreamResult<Self, TS::Error, Self::Error> {
501        let min_cap = quads.size_hint_quads().0;
502        let mut s = HashSet::<_, S>::with_capacity_and_hasher(min_cap, S::default());
503        quads
504            .for_each_quad(|q| {
505                s.insert((
506                    q.g().map(Term::into_term),
507                    [q.s().into_term(), q.p().into_term(), q.o().into_term()],
508                ));
509            })
510            .map_err(SourceError)?;
511        Ok(s)
512    }
513}
514
515impl<T, S> MutableDataset for HashSet<Gspo<T>, S>
516where
517    T: Term + Eq + FromTerm + Hash,
518    S: BuildHasher + Default,
519{
520    type MutationError = Infallible;
521
522    fn insert<TS, TP, TO, TG>(
523        &mut self,
524        s: TS,
525        p: TP,
526        o: TO,
527        g: GraphName<TG>,
528    ) -> MdResult<Self, bool>
529    where
530        TS: Term,
531        TP: Term,
532        TO: Term,
533        TG: Term,
534    {
535        Ok(self.insert((
536            g.map(Term::into_term),
537            [s.into_term(), p.into_term(), o.into_term()],
538        )))
539    }
540
541    fn remove<TS, TP, TO, TG>(
542        &mut self,
543        s: TS,
544        p: TP,
545        o: TO,
546        g: GraphName<TG>,
547    ) -> MdResult<Self, bool>
548    where
549        TS: Term,
550        TP: Term,
551        TO: Term,
552        TG: Term,
553    {
554        Ok(self.remove(&(
555            g.map(Term::into_term),
556            [s.into_term(), p.into_term(), o.into_term()],
557        )))
558    }
559}
560
561impl<T: Quad, S> SetDataset for HashSet<T, S> {}
562
563// BTreeSet of quads
564
565/// NB: This is a straighforward and minimal implementation,
566/// not taking advantage of the order of terms to optimize [`Dataset::quads_matching`]
567/// nor other methods.
568impl<Q: Quad> Dataset for BTreeSet<Q> {
569    type Error = Infallible;
570    type Quad<'x> = Spog<QBorrowTerm<'x, Q>> where Self: 'x;
571
572    fn quads(&self) -> DQuadSource<Self> {
573        Box::new(self.iter().map(Quad::spog).map(Ok))
574    }
575}
576
577impl<T> CollectibleDataset for BTreeSet<Spog<T>>
578where
579    T: Term + FromTerm + Ord,
580{
581    fn from_quad_source<TS: QuadSource>(
582        mut quads: TS,
583    ) -> StreamResult<Self, TS::Error, Self::Error> {
584        let mut s = BTreeSet::new();
585        quads
586            .for_each_quad(|q| {
587                s.insert((
588                    [q.s().into_term(), q.p().into_term(), q.o().into_term()],
589                    q.g().map(Term::into_term),
590                ));
591            })
592            .map_err(SourceError)?;
593        Ok(s)
594    }
595}
596
597impl<T> MutableDataset for BTreeSet<Spog<T>>
598where
599    T: Term + FromTerm + Ord,
600{
601    type MutationError = Infallible;
602
603    fn insert<TS, TP, TO, TG>(
604        &mut self,
605        s: TS,
606        p: TP,
607        o: TO,
608        g: GraphName<TG>,
609    ) -> MdResult<Self, bool>
610    where
611        TS: Term,
612        TP: Term,
613        TO: Term,
614        TG: Term,
615    {
616        Ok(self.insert((
617            [s.into_term(), p.into_term(), o.into_term()],
618            g.map(Term::into_term),
619        )))
620    }
621
622    fn remove<TS, TP, TO, TG>(
623        &mut self,
624        s: TS,
625        p: TP,
626        o: TO,
627        g: GraphName<TG>,
628    ) -> MdResult<Self, bool>
629    where
630        TS: Term,
631        TP: Term,
632        TO: Term,
633        TG: Term,
634    {
635        Ok(self.remove(&(
636            [s.into_term(), p.into_term(), o.into_term()],
637            g.map(Term::into_term),
638        )))
639    }
640}
641
642impl<T> CollectibleDataset for BTreeSet<Gspo<T>>
643where
644    T: Term + FromTerm + Ord,
645{
646    fn from_quad_source<TS: QuadSource>(
647        mut quads: TS,
648    ) -> StreamResult<Self, TS::Error, Self::Error> {
649        let mut s = BTreeSet::new();
650        quads
651            .for_each_quad(|q| {
652                s.insert((
653                    q.g().map(Term::into_term),
654                    [q.s().into_term(), q.p().into_term(), q.o().into_term()],
655                ));
656            })
657            .map_err(SourceError)?;
658        Ok(s)
659    }
660}
661
662impl<T> MutableDataset for BTreeSet<Gspo<T>>
663where
664    T: Term + FromTerm + Ord,
665{
666    type MutationError = Infallible;
667
668    fn insert<TS, TP, TO, TG>(
669        &mut self,
670        s: TS,
671        p: TP,
672        o: TO,
673        g: GraphName<TG>,
674    ) -> MdResult<Self, bool>
675    where
676        TS: Term,
677        TP: Term,
678        TO: Term,
679        TG: Term,
680    {
681        Ok(self.insert((
682            g.map(Term::into_term),
683            [s.into_term(), p.into_term(), o.into_term()],
684        )))
685    }
686
687    fn remove<TS, TP, TO, TG>(
688        &mut self,
689        s: TS,
690        p: TP,
691        o: TO,
692        g: GraphName<TG>,
693    ) -> MdResult<Self, bool>
694    where
695        TS: Term,
696        TP: Term,
697        TO: Term,
698        TG: Term,
699    {
700        Ok(self.remove(&(
701            g.map(Term::into_term),
702            [s.into_term(), p.into_term(), o.into_term()],
703        )))
704    }
705}
706
707impl<T: Quad> SetDataset for BTreeSet<T> {}
708
709#[cfg(test)]
710mod test {
711    use super::*;
712    // NB: implementation of Dataset by &D and &mut D are not tested,
713    // as the code is trivial to review.
714
715    // NB: implementation of Dataset by [Q] is tested indirectly,
716    // as the implementation of Dataset by Vec<Q> relies on it.
717
718    type VecAsDataset = Vec<Spog<SimpleTerm<'static>>>;
719    crate::test_dataset_impl!(vec, VecAsDataset, false);
720
721    // the following is only to test the test macro with is_gen=false
722    #[cfg(feature = "all_tests")]
723    crate::test_immutable_dataset_impl!(vec_strict, VecAsDataset, false, false);
724
725    #[cfg(feature = "all_tests")]
726    type HashSetAsDataset = HashSet<Spog<SimpleTerm<'static>>>;
727    #[cfg(feature = "all_tests")]
728    crate::test_dataset_impl!(hashset, HashSetAsDataset);
729
730    #[cfg(feature = "all_tests")]
731    type HashSetAsDataset2 = HashSet<Gspo<SimpleTerm<'static>>>;
732    #[cfg(feature = "all_tests")]
733    crate::test_dataset_impl!(hashset2, HashSetAsDataset2);
734
735    #[cfg(feature = "all_tests")]
736    type BTreeSetAsDataset = BTreeSet<Spog<SimpleTerm<'static>>>;
737    #[cfg(feature = "all_tests")]
738    crate::test_dataset_impl!(btreeset, BTreeSetAsDataset);
739
740    #[cfg(feature = "all_tests")]
741    type BTreeSetAsDataset2 = BTreeSet<Gspo<SimpleTerm<'static>>>;
742    #[cfg(feature = "all_tests")]
743    crate::test_dataset_impl!(btreeset2, BTreeSetAsDataset2);
744}