sophia_api/source/
_triple.rs1use std::error::Error;
2
3use super::*;
4use crate::graph::{CollectibleGraph, Graph, MutableGraph};
5use crate::triple::Triple;
6
7pub trait TripleSource: Source + IsTripleSource {
17 #[inline]
23 fn try_for_some_triple<E, F>(&mut self, mut f: F) -> StreamResult<bool, Self::Error, E>
24 where
25 E: Error + Send + Sync + 'static,
26 F: FnMut(TSTriple<Self>) -> Result<(), E>,
27 {
28 self.try_for_some_item(|i| f(Self::i2t(i)))
29 }
30
31 #[inline]
35 fn try_for_each_triple<F, E>(&mut self, mut f: F) -> StreamResult<(), Self::Error, E>
36 where
37 F: FnMut(TSTriple<Self>) -> Result<(), E>,
38 E: Error + Send + Sync + 'static,
39 {
40 self.try_for_each_item(|i| f(Self::i2t(i)))
41 }
42
43 #[inline]
49 fn for_some_triple<F>(&mut self, mut f: F) -> Result<bool, Self::Error>
50 where
51 F: FnMut(TSTriple<Self>),
52 {
53 self.for_some_item(|i| f(Self::i2t(i)))
54 }
55
56 #[inline]
60 fn for_each_triple<F>(&mut self, mut f: F) -> Result<(), Self::Error>
61 where
62 F: FnMut(TSTriple<Self>),
63 {
64 self.for_each_item(|i| f(Self::i2t(i)))
65 }
66
67 #[inline]
69 fn filter_triples<'f, F>(
70 self,
71 mut predicate: F,
72 ) -> filter::FilterTripleSource<Self, impl FnMut(&Self::Item<'_>) -> bool + 'f>
73 where
74 Self: Sized,
75 F: FnMut(&TSTriple<Self>) -> bool + 'f,
76 {
77 filter::FilterTripleSource(self.filter_items(move |i| predicate(Self::ri2t(i))))
78 }
79
80 #[inline]
84 fn filter_map_triples<'f, F, T>(
85 self,
86 mut filter_map: F,
87 ) -> filter_map::FilterMapSource<Self, impl FnMut(Self::Item<'_>) -> Option<T> + 'f>
88 where
89 Self: Sized,
90 F: FnMut(TSTriple<Self>) -> Option<T> + 'f,
91 {
92 self.filter_map_items(move |i| filter_map(Self::i2t(i)))
93 }
94
95 #[inline]
110 fn map_triples<'m, F, T>(
111 self,
112 mut map: F,
113 ) -> map::MapSource<Self, impl FnMut(Self::Item<'_>) -> T + 'm>
114 where
115 Self: Sized,
116 F: FnMut(TSTriple<Self>) -> T + 'm,
117 {
118 self.map_items(move |i| map(Self::i2t(i)))
119 }
120
121 fn size_hint_triples(&self) -> (usize, Option<usize>) {
125 self.size_hint_items()
126 }
127
128 #[inline]
130 fn to_quads(self) -> convert::ToQuads<Self>
131 where
132 Self: Sized,
133 {
134 convert::ToQuads(self)
135 }
136
137 #[inline]
139 fn collect_triples<G>(self) -> StreamResult<G, Self::Error, <G as Graph>::Error>
140 where
141 Self: Sized,
142 G: CollectibleGraph,
143 {
144 G::from_triple_source(self)
145 }
146
147 #[inline]
151 fn add_to_graph<G: MutableGraph>(
152 self,
153 graph: &mut G,
154 ) -> StreamResult<usize, Self::Error, <G as MutableGraph>::MutationError>
155 where
156 Self: Sized,
157 {
158 graph.insert_all(self)
159 }
160}
161
162impl<T> TripleSource for T where T: Source + IsTripleSource {}
164
165pub type TSTriple<'a, TS> = <TS as IsTripleSource>::Triple<'a>;
172
173mod sealed {
174 use super::*;
175
176 pub trait IsTripleSource: Source {
177 type Triple<'x>: Triple;
178 fn i2t(i: Self::Item<'_>) -> Self::Triple<'_>;
179 fn ri2t<'a, 'b>(i: &'a Self::Item<'b>) -> &'a Self::Triple<'b>;
180 }
181
182 impl<TS> IsTripleSource for TS
183 where
184 TS: Source,
185 for<'x> TS::Item<'x>: Triple,
186 {
187 type Triple<'x> = Self::Item<'x>;
188
189 fn i2t(i: Self::Item<'_>) -> Self::Triple<'_> {
190 i
191 }
192
193 fn ri2t<'a, 'b>(i: &'a Self::Item<'b>) -> &'a Self::Triple<'b> {
194 i
195 }
196 }
197}
198use sealed::IsTripleSource;
199
200#[cfg(test)]
201mod check_triple_source {
202 use super::*;
203 use crate::term::{SimpleTerm, Term};
204 use sophia_iri::IriRef;
205 use std::convert::Infallible;
206 use std::fmt::Write;
207
208 #[allow(dead_code)] pub fn check_for_each<TS>(ts: TS)
210 where
211 TS: Source + TripleSource,
212 {
213 ts.filter_triples(|t| t.s().is_iri())
214 .for_each_triple(|t| println!("{:?}", t.s()))
215 .unwrap();
216 }
217
218 #[allow(dead_code)] fn check_triple_source_impl_generic_graph<G: Graph>(g: &G) {
220 g.triples()
221 .filter_triples(|t| t.s().is_iri())
222 .for_each_triple(|t| println!("{:?}", t.s()))
223 .unwrap();
224 }
225
226 #[allow(dead_code)] fn check_triple_source_impl_concrete_graph(g: &[[SimpleTerm; 3]]) {
228 g.triples()
229 .filter_triples(|t| t.s().is_iri())
230 .for_each_triple(|t| println!("{:?}", t.s()))
231 .unwrap();
232 }
233
234 struct DummyParser<'a> {
236 tokens: &'a [usize],
237 pos: usize,
238 buffers: [String; 3],
239 }
240
241 impl<'a> Source for DummyParser<'a> {
242 type Item<'x> = [SimpleTerm<'x>; 3];
243 type Error = Infallible;
244
245 fn try_for_some_item<E2, F>(&mut self, mut f: F) -> StreamResult<bool, Self::Error, E2>
246 where
247 E2: Error,
248 F: FnMut(Self::Item<'_>) -> Result<(), E2>,
249 {
250 if self.tokens.len() - self.pos < 3 {
251 Ok(false)
252 } else {
253 for i in 0..3 {
254 write!(&mut self.buffers[i], "b{}", self.tokens[self.pos + i]).unwrap();
255 }
256 let t = [
257 IriRef::new_unchecked(&self.buffers[0][..]).into_term(),
258 IriRef::new_unchecked(&self.buffers[1][..]).into_term(),
259 IriRef::new_unchecked(&self.buffers[2][..]).into_term(),
260 ];
261 f(t).map_err(SinkError).map(|_| true)
262 }
263 }
264 }
265
266 #[allow(dead_code)] fn check_triple_source_impl_by_iterator(v: Vec<Result<[SimpleTerm; 3], std::io::Error>>) {
268 v.into_iter()
269 .for_each_triple(|t| println!("{:?}", t.s()))
270 .unwrap();
271 }
272}