sophia_api/graph/
_foreign_impl.rs

1use super::*;
2use crate::source::SourceError;
3use crate::term::FromTerm;
4use crate::triple::TBorrowTerm;
5use std::collections::{BTreeSet, HashSet};
6use std::convert::Infallible;
7use std::hash::{BuildHasher, Hash};
8
9//
10// foreign implementations
11//
12
13// reference to Graph
14
15impl<'a, T: Graph + ?Sized> Graph for &'a T {
16    type Triple<'x> = T::Triple<'x> where Self: 'x;
17
18    type Error = T::Error;
19
20    fn triples(&self) -> impl Iterator<Item = GResult<Self, Self::Triple<'_>>> + '_ {
21        T::triples(*self)
22    }
23
24    fn triples_matching<'s, S, P, O>(
25        &'s self,
26        sm: S,
27        pm: P,
28        om: O,
29    ) -> impl Iterator<Item = GResult<Self, Self::Triple<'s>>> + 's
30    where
31        S: TermMatcher + 's,
32        P: TermMatcher + 's,
33        O: TermMatcher + 's,
34    {
35        T::triples_matching(*self, sm, pm, om)
36    }
37
38    fn contains<TS, TP, TO>(&self, s: TS, p: TP, o: TO) -> GResult<Self, bool>
39    where
40        TS: Term,
41        TP: Term,
42        TO: Term,
43    {
44        T::contains(*self, s, p, o)
45    }
46
47    fn subjects(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
48        T::subjects(*self)
49    }
50
51    fn predicates(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
52        T::predicates(*self)
53    }
54
55    fn objects(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
56        T::objects(*self)
57    }
58
59    fn iris(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
60        T::iris(*self)
61    }
62
63    fn blank_nodes(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
64        T::blank_nodes(*self)
65    }
66
67    fn literals(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
68        T::literals(*self)
69    }
70
71    fn quoted_triples<'s>(&'s self) -> Box<dyn Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_>
72    where
73        GTerm<'s, Self>: Clone,
74    {
75        T::quoted_triples(*self)
76    }
77
78    fn variables(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
79        T::variables(*self)
80    }
81}
82
83// NB: this one is required so that &'a mut T can also implement MutableDataset
84impl<'a, T: Graph + ?Sized> Graph for &'a mut T {
85    type Triple<'x> = T::Triple<'x> where Self: 'x;
86
87    type Error = T::Error;
88
89    fn triples(&self) -> impl Iterator<Item = GResult<Self, Self::Triple<'_>>> + '_ {
90        T::triples(*self)
91    }
92
93    fn triples_matching<'s, S, P, O>(
94        &'s self,
95        sm: S,
96        pm: P,
97        om: O,
98    ) -> impl Iterator<Item = GResult<Self, Self::Triple<'s>>> + 's
99    where
100        S: TermMatcher + 's,
101        P: TermMatcher + 's,
102        O: TermMatcher + 's,
103    {
104        T::triples_matching(*self, sm, pm, om)
105    }
106
107    fn contains<TS, TP, TO>(&self, s: TS, p: TP, o: TO) -> GResult<Self, bool>
108    where
109        TS: Term,
110        TP: Term,
111        TO: Term,
112    {
113        T::contains(*self, s, p, o)
114    }
115
116    fn subjects(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
117        T::subjects(*self)
118    }
119
120    fn predicates(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
121        T::predicates(*self)
122    }
123
124    fn objects(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
125        T::objects(*self)
126    }
127
128    fn iris(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
129        T::iris(*self)
130    }
131
132    fn blank_nodes(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
133        T::blank_nodes(*self)
134    }
135
136    fn literals(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
137        T::literals(*self)
138    }
139
140    fn quoted_triples<'s>(&'s self) -> Box<dyn Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_>
141    where
142        GTerm<'s, Self>: Clone,
143    {
144        T::quoted_triples(*self)
145    }
146
147    fn variables(&self) -> impl Iterator<Item = GResult<Self, GTerm<'_, Self>>> + '_ {
148        T::variables(*self)
149    }
150}
151
152impl<'a, T: MutableGraph + ?Sized> MutableGraph for &'a mut T {
153    type MutationError = T::MutationError;
154
155    fn insert<TS, TP, TO>(&mut self, s: TS, p: TP, o: TO) -> MgResult<Self, bool>
156    where
157        TS: Term,
158        TP: Term,
159        TO: Term,
160    {
161        T::insert(*self, s, p, o)
162    }
163
164    fn remove<TS, TP, TO>(&mut self, s: TS, p: TP, o: TO) -> MgResult<Self, bool>
165    where
166        TS: Term,
167        TP: Term,
168        TO: Term,
169    {
170        T::remove(*self, s, p, o)
171    }
172
173    fn insert_all<TS: TripleSource>(
174        &mut self,
175        src: TS,
176    ) -> StreamResult<usize, TS::Error, Self::MutationError> {
177        T::insert_all(*self, src)
178    }
179
180    fn remove_all<TS: TripleSource>(
181        &mut self,
182        src: TS,
183    ) -> StreamResult<usize, TS::Error, Self::MutationError> {
184        T::remove_all(*self, src)
185    }
186
187    fn remove_matching<S, P, O>(
188        &mut self,
189        ms: S,
190        mp: P,
191        mo: O,
192    ) -> Result<usize, Self::MutationError>
193    where
194        S: TermMatcher,
195        P: TermMatcher,
196        O: TermMatcher,
197        Self::MutationError: From<Self::Error>,
198    {
199        T::remove_matching(*self, ms, mp, mo)
200    }
201
202    fn retain_matching<S, P, O>(&mut self, ms: S, mp: P, mo: O) -> Result<(), Self::MutationError>
203    where
204        S: TermMatcher,
205        P: TermMatcher,
206        O: TermMatcher,
207        Self::MutationError: From<Self::Error>,
208    {
209        T::retain_matching(*self, ms, mp, mo)
210    }
211}
212
213// slice of triples
214
215impl<T: Triple> Graph for [T] {
216    type Error = Infallible;
217    type Triple<'x> = [TBorrowTerm<'x, T>; 3] where Self: 'x;
218
219    fn triples(&self) -> impl Iterator<Item = GResult<Self, Self::Triple<'_>>> + '_ {
220        self.iter().map(Triple::spo).map(Ok)
221    }
222}
223
224// Vec of triples
225
226impl<T: Triple> Graph for Vec<T> {
227    type Error = Infallible;
228    type Triple<'x> = [TBorrowTerm<'x, T>; 3] where Self: 'x;
229
230    fn triples(&self) -> impl Iterator<Item = GResult<Self, Self::Triple<'_>>> + '_ {
231        self[..].triples()
232    }
233}
234
235impl<T> CollectibleGraph for Vec<[T; 3]>
236where
237    T: Term + FromTerm,
238{
239    fn from_triple_source<TS: TripleSource>(
240        mut triples: TS,
241    ) -> StreamResult<Self, TS::Error, Self::Error> {
242        let min_cap = triples.size_hint_triples().0;
243        let mut v = Vec::with_capacity(min_cap);
244        triples
245            .for_each_triple(|t| v.push([t.s().into_term(), t.p().into_term(), t.o().into_term()]))
246            .map_err(SourceError)?;
247        Ok(v)
248    }
249}
250
251impl<T> MutableGraph for Vec<[T; 3]>
252where
253    T: Term + FromTerm,
254{
255    type MutationError = Infallible;
256
257    fn insert<TS, TP, TO>(&mut self, s: TS, p: TP, o: TO) -> MgResult<Self, bool>
258    where
259        TS: Term,
260        TP: Term,
261        TO: Term,
262    {
263        self.push([s.into_term(), p.into_term(), o.into_term()]);
264        Ok(true)
265    }
266
267    fn remove<TS, TP, TO>(&mut self, s: TS, p: TP, o: TO) -> MgResult<Self, bool>
268    where
269        TS: Term,
270        TP: Term,
271        TO: Term,
272    {
273        let s = s.borrow_term();
274        let p = p.borrow_term();
275        let o = o.borrow_term();
276        let mut i = 0;
277        while i < self.len() {
278            if self[i].matched_by([s], [p], [o]) {
279                self.swap_remove(i);
280            } else {
281                i += 1;
282            }
283        }
284        Ok(true)
285    }
286}
287
288// HashSet of triples
289
290impl<T: Triple, S> Graph for HashSet<T, S> {
291    type Error = Infallible;
292    type Triple<'x> = [TBorrowTerm<'x, T>; 3] where Self: 'x;
293
294    fn triples(&self) -> impl Iterator<Item = GResult<Self, Self::Triple<'_>>> + '_ {
295        self.iter().map(Triple::spo).map(Ok)
296    }
297}
298
299impl<T, S> CollectibleGraph for HashSet<[T; 3], S>
300where
301    T: Term + Eq + FromTerm + Hash,
302    S: BuildHasher + Default,
303{
304    fn from_triple_source<TS: TripleSource>(
305        mut triples: TS,
306    ) -> StreamResult<Self, TS::Error, Self::Error> {
307        let min_cap = triples.size_hint_triples().0;
308        let mut s = HashSet::<_, S>::with_capacity_and_hasher(min_cap, S::default());
309        triples
310            .for_each_triple(|t| {
311                s.insert([t.s().into_term(), t.p().into_term(), t.o().into_term()]);
312            })
313            .map_err(SourceError)?;
314        Ok(s)
315    }
316}
317
318impl<T, S> MutableGraph for HashSet<[T; 3], S>
319where
320    T: Term + Eq + FromTerm + Hash,
321    S: BuildHasher + Default,
322{
323    type MutationError = Infallible;
324
325    fn insert<TS, TP, TO>(&mut self, s: TS, p: TP, o: TO) -> MgResult<Self, bool>
326    where
327        TS: Term,
328        TP: Term,
329        TO: Term,
330    {
331        Ok(self.insert([s.into_term(), p.into_term(), o.into_term()]))
332    }
333
334    fn remove<TS, TP, TO>(&mut self, s: TS, p: TP, o: TO) -> MgResult<Self, bool>
335    where
336        TS: Term,
337        TP: Term,
338        TO: Term,
339    {
340        Ok(self.remove(&[s.into_term(), p.into_term(), o.into_term()]))
341    }
342}
343
344impl<T: Triple, S> SetGraph for HashSet<T, S> {}
345
346// BTreeSet of triples
347
348/// NB: This is a straightforward and minimal implementation,
349/// not taking advantage of the order of terms to optimize [`Graph::triples_matching`]
350/// nor other methods.
351impl<T: Triple> Graph for BTreeSet<T> {
352    type Error = Infallible;
353    type Triple<'x> = [TBorrowTerm<'x, T>; 3] where Self: 'x;
354
355    fn triples(&self) -> impl Iterator<Item = GResult<Self, Self::Triple<'_>>> + '_ {
356        self.iter().map(Triple::spo).map(Ok)
357    }
358}
359
360impl<T> CollectibleGraph for BTreeSet<[T; 3]>
361where
362    T: Term + FromTerm + Ord,
363{
364    fn from_triple_source<TS: TripleSource>(
365        mut triples: TS,
366    ) -> StreamResult<Self, TS::Error, Self::Error> {
367        let mut s = BTreeSet::new();
368        triples
369            .for_each_triple(|t| {
370                s.insert([t.s().into_term(), t.p().into_term(), t.o().into_term()]);
371            })
372            .map_err(SourceError)?;
373        Ok(s)
374    }
375}
376
377impl<T> MutableGraph for BTreeSet<[T; 3]>
378where
379    T: Term + FromTerm + Ord,
380{
381    type MutationError = Infallible;
382
383    fn insert<TS, TP, TO>(&mut self, s: TS, p: TP, o: TO) -> MgResult<Self, bool>
384    where
385        TS: Term,
386        TP: Term,
387        TO: Term,
388    {
389        Ok(self.insert([s.into_term(), p.into_term(), o.into_term()]))
390    }
391
392    fn remove<TS, TP, TO>(&mut self, s: TS, p: TP, o: TO) -> MgResult<Self, bool>
393    where
394        TS: Term,
395        TP: Term,
396        TO: Term,
397    {
398        Ok(self.remove(&[s.into_term(), p.into_term(), o.into_term()]))
399    }
400}
401
402impl<T: Triple> SetGraph for BTreeSet<T> {}
403
404#[cfg(test)]
405mod test {
406    use super::*;
407
408    // NB: implementation of Graph by &G and &mut G are not tested,
409    // as the code is trivial to review.
410
411    // NB: implementation of Graph by [T] is tested indirectly,
412    // as the implementation of Graph by Vec<T> relies on it.
413
414    type VecAsGraph = Vec<[SimpleTerm<'static>; 3]>;
415    crate::test_graph_impl!(vec, VecAsGraph, false);
416
417    // the following is only to test the test macro with is_gen=false
418    #[cfg(feature = "all_tests")]
419    crate::test_immutable_graph_impl!(vec_strict, VecAsGraph, false, false);
420
421    #[cfg(feature = "all_tests")]
422    type HashSetAsGraph = HashSet<[SimpleTerm<'static>; 3]>;
423    #[cfg(feature = "all_tests")]
424    crate::test_graph_impl!(hashset, HashSetAsGraph);
425
426    #[cfg(feature = "all_tests")]
427    type BTreeSetAsGraph = BTreeSet<[crate::term::SimpleTerm<'static>; 3]>;
428    #[cfg(feature = "all_tests")]
429    crate::test_graph_impl!(btreeset, BTreeSetAsGraph);
430}