1use super::*;
8
9pub struct FilterSource<S, P> {
11 pub(super) source: S,
12 pub(super) predicate: P,
13}
14
15impl<S, P> Source for FilterSource<S, P>
16where
17 S: Source,
18 P: FnMut(&S::Item<'_>) -> bool,
19{
20 type Item<'x> = S::Item<'x>;
21 type Error = S::Error;
22
23 fn try_for_some_item<E, F>(&mut self, mut f: F) -> StreamResult<bool, Self::Error, E>
24 where
25 E: std::error::Error + Send + Sync + 'static,
26 F: FnMut(Self::Item<'_>) -> Result<(), E>,
27 {
28 let p = &mut self.predicate;
29 self.source.try_for_some_item(|i| {
30 if p(&i) {
31 f(i)?;
32 }
33 Ok(())
34 })
35 }
36
37 fn size_hint_items(&self) -> (usize, Option<usize>) {
38 (0, self.source.size_hint_items().1)
39 }
40}
41
42mod _triple {
43 use super::*;
44
45 pub struct FilterTripleSource<S, P>(pub(crate) FilterSource<S, P>);
47
48 impl<S, P> Source for FilterTripleSource<S, P>
49 where
50 S: TripleSource,
51 P: FnMut(&S::Item<'_>) -> bool,
52 {
53 type Item<'x> = TSTriple<'x, S>;
54 type Error = S::Error;
55
56 fn try_for_some_item<E, F>(&mut self, mut f: F) -> StreamResult<bool, Self::Error, E>
57 where
58 E: std::error::Error + Send + Sync + 'static,
59 F: FnMut(Self::Item<'_>) -> Result<(), E>,
60 {
61 self.0.try_for_some_item(|i| f(S::i2t(i)))
62 }
63
64 fn size_hint_items(&self) -> (usize, Option<usize>) {
65 (0, self.0.size_hint_items().1)
66 }
67 }
68}
69pub use _triple::*;
70
71mod _quad {
72 use super::*;
73
74 pub struct FilterQuadSource<S, P>(pub(crate) FilterSource<S, P>);
76
77 impl<S, P> Source for FilterQuadSource<S, P>
78 where
79 S: QuadSource,
80 P: FnMut(&S::Item<'_>) -> bool,
81 {
82 type Item<'x> = QSQuad<'x, S>;
83 type Error = S::Error;
84
85 fn try_for_some_item<E, F>(&mut self, mut f: F) -> StreamResult<bool, Self::Error, E>
86 where
87 E: std::error::Error + Send + Sync + 'static,
88 F: FnMut(Self::Item<'_>) -> Result<(), E>,
89 {
90 self.0.try_for_some_item(|i| f(S::i2q(i)))
91 }
92
93 fn size_hint_items(&self) -> (usize, Option<usize>) {
94 (0, self.0.size_hint_items().1)
95 }
96 }
97}
98pub use _quad::*;
99
100#[cfg(test)]
101mod test {
102 use super::*;
103 use crate::dataset::{Dataset, MutableDataset};
104 use crate::graph::{Graph, MutableGraph};
105 use crate::quad::{Quad, Spog};
106 use crate::term::ez_term;
107 use crate::term::{SimpleTerm, Term};
108 use crate::triple::Triple;
109
110 #[test]
111 fn s_filter_items() {
112 let v = vec!["foo", "bar", "baz"];
113 let mut w = vec![];
114 v.into_iter()
115 .into_source()
116 .filter_items(|t| t.starts_with('b'))
117 .for_each_item(|t| {
118 w.push(t);
119 })
120 .unwrap();
121 assert_eq!(w, vec!["bar", "baz",],)
122 }
123
124 #[test]
125 fn ts_filter_triples() {
126 let g = vec![
127 [ez_term(":a"), ez_term(":b"), ez_term(":c")],
128 [ez_term(":d"), ez_term(":e"), ez_term(":f")],
129 [ez_term(":g"), ez_term(":h"), ez_term(":i")],
130 ];
131 let mut h: Vec<[SimpleTerm; 3]> = vec![];
132 g.triples()
133 .filter_triples(|t| !Term::eq(t.p(), ez_term(":e")))
134 .for_each_triple(|t| {
135 h.insert_triple(t).unwrap();
136 })
137 .unwrap();
138 assert_eq!(
139 h,
140 vec![
141 [ez_term(":a"), ez_term(":b"), ez_term(":c")],
142 [ez_term(":g"), ez_term(":h"), ez_term(":i")],
143 ]
144 )
145 }
146
147 #[test]
148 fn qs_filter_triples() {
149 let d = vec![
150 ([ez_term(":a"), ez_term(":b"), ez_term(":c")], None),
151 ([ez_term(":d"), ez_term(":e"), ez_term(":f")], None),
152 ([ez_term(":g"), ez_term(":h"), ez_term(":i")], None),
153 ];
154 let mut h: Vec<Spog<SimpleTerm>> = vec![];
155 d.quads()
156 .filter_quads(|q| !Term::eq(q.p(), ez_term(":e")))
157 .for_each_quad(|q| {
158 h.insert_quad(q).unwrap();
159 })
160 .unwrap();
161 assert_eq!(
162 h,
163 vec![
164 ([ez_term(":a"), ez_term(":b"), ez_term(":c")], None),
165 ([ez_term(":g"), ez_term(":h"), ez_term(":i")], None),
166 ]
167 )
168 }
169}