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