sophia_api/source/
_quad.rs1use std::error::Error;
2
3use super::*;
4use crate::dataset::{CollectibleDataset, Dataset, MutableDataset};
5use crate::quad::Quad;
6
7pub trait QuadSource: Source + IsQuadSource {
17 #[inline]
23 fn try_for_some_quad<E, F>(&mut self, mut f: F) -> StreamResult<bool, Self::Error, E>
24 where
25 E: Error + Send + Sync + 'static,
26 F: FnMut(Self::Quad<'_>) -> Result<(), E>,
27 {
28 self.try_for_some_item(|i| f(Self::i2q(i)))
29 }
30
31 #[inline]
35 fn try_for_each_quad<F, E>(&mut self, mut f: F) -> StreamResult<(), Self::Error, E>
36 where
37 F: FnMut(Self::Quad<'_>) -> Result<(), E>,
38 E: Error + Send + Sync + 'static,
39 {
40 self.try_for_each_item(|i| f(Self::i2q(i)))
41 }
42
43 #[inline]
49 fn for_some_quad<F>(&mut self, mut f: F) -> Result<bool, Self::Error>
50 where
51 F: FnMut(Self::Quad<'_>),
52 {
53 self.for_some_item(|i| f(Self::i2q(i)))
54 }
55
56 #[inline]
60 fn for_each_quad<F>(&mut self, mut f: F) -> Result<(), Self::Error>
61 where
62 F: FnMut(Self::Quad<'_>),
63 {
64 self.for_each_item(|i| f(Self::i2q(i)))
65 }
66
67 #[inline]
69 fn filter_quads<'f, F>(
70 self,
71 mut predicate: F,
72 ) -> filter::FilterQuadSource<Self, impl FnMut(&Self::Item<'_>) -> bool + 'f>
73 where
74 Self: Sized,
75 F: FnMut(&QSQuad<Self>) -> bool + 'f,
76 {
77 filter::FilterQuadSource(self.filter_items(move |i| predicate(Self::ri2q(i))))
78 }
79
80 #[inline]
84 fn filter_map_quads<'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(Self::Quad<'_>) -> Option<T> + 'f,
91 {
92 self.filter_map_items(move |i| filter_map(Self::i2q(i)))
93 }
94
95 #[inline]
110 fn map_quads<'f, F, T>(
111 self,
112 mut map: F,
113 ) -> map::MapSource<Self, impl FnMut(Self::Item<'_>) -> T + 'f>
114 where
115 Self: Sized,
116 F: FnMut(Self::Quad<'_>) -> T + 'f,
117 {
118 self.map_items(move |i| map(Self::i2q(i)))
119 }
120
121 fn to_triples(self) -> convert::ToTriples<Self>
123 where
124 Self: Sized,
125 {
126 convert::ToTriples(self)
127 }
128
129 fn size_hint_quads(&self) -> (usize, Option<usize>) {
133 (0, None)
134 }
135
136 #[inline]
138 fn collect_quads<D>(self) -> StreamResult<D, Self::Error, <D as Dataset>::Error>
139 where
140 Self: Sized,
141 for<'x> Self::Quad<'x>: Quad,
142 D: CollectibleDataset,
143 {
144 D::from_quad_source(self)
145 }
146
147 #[inline]
151 fn add_to_dataset<D: MutableDataset>(
152 self,
153 dataset: &mut D,
154 ) -> StreamResult<usize, Self::Error, <D as MutableDataset>::MutationError>
155 where
156 Self: Sized,
157 for<'x> Self::Quad<'x>: Quad,
158 {
159 dataset.insert_all(self)
160 }
161}
162
163impl<T> QuadSource for T where T: Source + IsQuadSource {}
165
166pub type QSQuad<'a, TS> = <TS as IsQuadSource>::Quad<'a>;
173
174mod sealed {
175 use super::*;
176
177 pub trait IsQuadSource: Source {
178 type Quad<'x>: Quad;
179 fn i2q(i: Self::Item<'_>) -> Self::Quad<'_>;
180 fn ri2q<'a, 'b>(i: &'a Self::Item<'b>) -> &'a Self::Quad<'b>;
181 }
182
183 impl<TS> IsQuadSource for TS
184 where
185 TS: Source,
186 for<'x> TS::Item<'x>: Quad,
187 {
188 type Quad<'x> = Self::Item<'x>;
189
190 fn i2q(i: Self::Item<'_>) -> Self::Quad<'_> {
191 i
192 }
193
194 fn ri2q<'a, 'b>(i: &'a Self::Item<'b>) -> &'a Self::Quad<'b> {
195 i
196 }
197 }
198}
199use sealed::IsQuadSource;
200
201#[cfg(test)]
202mod check_quad_source {
203 use super::*;
204 use crate::quad::Spog;
205 use crate::term::{SimpleTerm, Term};
206 use sophia_iri::IriRef;
207 use std::convert::Infallible;
208 use std::fmt::Write;
209
210 #[allow(dead_code)] pub fn check_for_each<TS>(ts: TS)
212 where
213 TS: QuadSource,
214 {
215 ts.filter_quads(|t| t.s().is_iri())
216 .for_each_quad(|t| println!("{:?}", t.s()))
217 .unwrap();
218 }
219
220 #[allow(dead_code)] fn check_quad_source_impl_generic_dataset<D: Dataset>(d: &D) {
222 d.quads()
223 .filter_quads(|t| t.s().is_iri())
224 .for_each_quad(|t| println!("{:?}", t.s()))
225 .unwrap();
226 }
227
228 #[allow(dead_code)] fn check_quad_source_impl_concrete_dataset(d: &[Spog<SimpleTerm>]) {
230 d.quads()
231 .filter_quads(|t| t.s().is_iri())
232 .for_each_quad(|t| println!("{:?}", t.s()))
233 .unwrap();
234 }
235
236 struct DummyParser<'a> {
238 tokens: &'a [usize],
239 pos: usize,
240 buffers: [String; 3],
241 }
242
243 impl<'a> Source for DummyParser<'a> {
244 type Item<'x> = Spog<SimpleTerm<'x>>;
245 type Error = Infallible;
246
247 fn try_for_some_item<E2, F>(&mut self, mut f: F) -> StreamResult<bool, Self::Error, E2>
248 where
249 E2: Error,
250 F: FnMut(Self::Item<'_>) -> Result<(), E2>,
251 {
252 if self.tokens.len() - self.pos < 3 {
253 Ok(false)
254 } else {
255 for i in 0..3 {
256 write!(&mut self.buffers[i], "b{}", self.tokens[self.pos + i]).unwrap();
257 }
258 let q = (
259 [
260 IriRef::new_unchecked(&self.buffers[0][..]).into_term(),
261 IriRef::new_unchecked(&self.buffers[1][..]).into_term(),
262 IriRef::new_unchecked(&self.buffers[2][..]).into_term(),
263 ],
264 None,
265 );
266 f(q).map_err(SinkError).map(|_| true)
267 }
268 }
269 }
270
271 #[allow(dead_code)] fn check_quad_source_impl_by_iterator(v: Vec<Result<Spog<SimpleTerm>, std::io::Error>>) {
273 v.into_iter()
274 .for_each_quad(|q| println!("{:?}", q.s()))
275 .unwrap();
276 }
277
278 }