1use super::*;
3use std::{collections::VecDeque, error::Error};
4
5pub struct MapSource<S, F> {
7 pub(super) source: S,
8 pub(super) map: F,
9}
10
11impl<S, F, T> Source for MapSource<S, F>
12where
13 S: Source,
14 F: FnMut(S::Item<'_>) -> T,
15{
16 type Item<'x> = T;
17 type Error = S::Error;
18
19 fn try_for_some_item<E, F2>(&mut self, mut f: F2) -> StreamResult<bool, Self::Error, E>
20 where
21 E: Error + Send + Sync + 'static,
22 F2: FnMut(Self::Item<'_>) -> Result<(), E>,
23 {
24 let map = &mut self.map;
25 self.source.try_for_some_item(|t| f((map)(t)))
26 }
27
28 fn size_hint_items(&self) -> (usize, Option<usize>) {
29 self.source.size_hint_items()
30 }
31}
32
33impl<S, F, T> IntoIterator for MapSource<S, F>
34where
35 S: Source,
36 F: FnMut(S::Item<'_>) -> T,
37{
38 type Item = Result<T, S::Error>;
39 type IntoIter = MapSourceIterator<S, F, T, S::Error>;
40
41 fn into_iter(self) -> Self::IntoIter {
42 MapSourceIterator {
43 source: self.source,
44 map: self.map,
45 buffer: VecDeque::new(),
46 }
47 }
48}
49
50pub struct MapSourceIterator<S, F, T, E> {
52 source: S,
53 map: F,
54 buffer: VecDeque<Result<T, E>>,
55}
56
57impl<S, F, T> Iterator for MapSourceIterator<S, F, T, S::Error>
58where
59 S: Source,
60 F: FnMut(S::Item<'_>) -> T,
61{
62 type Item = Result<T, S::Error>;
63 fn next(&mut self) -> Option<Result<T, S::Error>> {
64 let mut remaining = true;
65 let mut buffer = VecDeque::new();
66 std::mem::swap(&mut self.buffer, &mut buffer);
67 while buffer.is_empty() && remaining {
68 let resb = self.source.for_some_item(|i| {
69 buffer.push_back(Ok((self.map)(i)));
70 });
71 match resb {
72 Ok(b) => {
73 remaining = b;
74 }
75 Err(err) => {
76 buffer.push_back(Err(err));
77 remaining = false;
78 }
79 }
80 }
81 std::mem::swap(&mut self.buffer, &mut buffer);
82 self.buffer.pop_front()
83 }
84
85 fn size_hint(&self) -> (usize, Option<usize>) {
86 self.source.size_hint_items()
87 }
88}
89
90#[cfg(test)]
91mod test {
92 use super::*;
93 use crate::dataset::{Dataset, MutableDataset};
94 use crate::graph::{Graph, MutableGraph};
95 use crate::quad::{Quad, Spog};
96 use crate::term::ez_term;
97 use crate::term::{SimpleTerm, Term};
98 use crate::triple::Triple;
99
100 #[test]
104 fn ts_map_to_triples() {
105 let g = vec![
106 [ez_term(":a"), ez_term(":b"), ez_term(":c")],
107 [ez_term(":d"), ez_term(":e"), ez_term(":f")],
108 [ez_term(":g"), ez_term(":h"), ez_term(":i")],
109 ];
110 let mut h: Vec<[SimpleTerm; 3]> = vec![];
111 g.triples()
112 .map_triples(|t| [t.o(), t.p(), t.s()])
113 .for_each_triple(|t| {
114 h.insert_triple(t).unwrap();
115 })
116 .unwrap();
117 assert_eq!(
118 h,
119 vec![
120 [ez_term(":c"), ez_term(":b"), ez_term(":a")],
121 [ez_term(":f"), ez_term(":e"), ez_term(":d")],
122 [ez_term(":i"), ez_term(":h"), ez_term(":g")],
123 ]
124 )
125 }
126
127 #[test]
128 fn ts_map_to_quads() {
129 let g = vec![
130 [ez_term(":a"), ez_term(":b"), ez_term(":c")],
131 [ez_term(":d"), ez_term(":e"), ez_term(":f")],
132 [ez_term(":g"), ez_term(":h"), ez_term(":i")],
133 ];
134 let mut h: Vec<Spog<SimpleTerm>> = vec![];
135 g.triples()
136 .map_triples(|t| ([t.o(), t.p(), t.s()], None))
137 .for_each_quad(|q| {
138 h.insert_quad(q).unwrap();
139 })
140 .unwrap();
141 assert_eq!(
142 h,
143 vec![
144 ([ez_term(":c"), ez_term(":b"), ez_term(":a")], None),
145 ([ez_term(":f"), ez_term(":e"), ez_term(":d")], None),
146 ([ez_term(":i"), ez_term(":h"), ez_term(":g")], None),
147 ]
148 )
149 }
150
151 #[test]
152 fn ts_map_iter() {
153 let g = vec![
154 [ez_term(":a"), ez_term(":b"), ez_term(":c")],
155 [ez_term(":d"), ez_term(":e"), ez_term(":f")],
156 [ez_term(":g"), ez_term(":h"), ez_term(":i")],
157 ];
158 let h: Result<Vec<String>, _> = g
159 .triples()
160 .map_triples(|t| t.s().iri().unwrap().to_string())
161 .into_iter()
162 .collect();
163 assert_eq!(
164 h.unwrap(),
165 vec![
166 "tag:a".to_string(),
167 "tag:d".to_string(),
168 "tag:g".to_string(),
169 ]
170 )
171 }
172
173 #[test]
177 fn qs_map_to_triples() {
178 let d = vec![
179 ([ez_term(":a"), ez_term(":b"), ez_term(":c")], None),
180 ([ez_term(":d"), ez_term(":e"), ez_term(":f")], None),
181 ([ez_term(":g"), ez_term(":h"), ez_term(":i")], None),
182 ];
183 let mut h: Vec<[SimpleTerm; 3]> = vec![];
184 d.quads()
185 .map_quads(|q| [q.o(), q.p(), q.s()])
186 .for_each_triple(|t| {
187 h.insert_triple(t).unwrap();
188 })
189 .unwrap();
190 assert_eq!(
191 h,
192 vec![
193 [ez_term(":c"), ez_term(":b"), ez_term(":a")],
194 [ez_term(":f"), ez_term(":e"), ez_term(":d")],
195 [ez_term(":i"), ez_term(":h"), ez_term(":g")],
196 ]
197 )
198 }
199
200 #[test]
201 fn qs_map_to_quads() {
202 let d = vec![
203 ([ez_term(":a"), ez_term(":b"), ez_term(":c")], None),
204 ([ez_term(":d"), ez_term(":e"), ez_term(":f")], None),
205 ([ez_term(":g"), ez_term(":h"), ez_term(":i")], None),
206 ];
207 let mut h: Vec<Spog<SimpleTerm>> = vec![];
208 d.quads()
209 .map_quads(|q| ([q.o(), q.p(), q.s()], q.g()))
210 .for_each_quad(|q| {
211 h.insert_quad(q).unwrap();
212 })
213 .unwrap();
214 assert_eq!(
215 h,
216 vec![
217 ([ez_term(":c"), ez_term(":b"), ez_term(":a")], None),
218 ([ez_term(":f"), ez_term(":e"), ez_term(":d")], None),
219 ([ez_term(":i"), ez_term(":h"), ez_term(":g")], None),
220 ]
221 )
222 }
223
224 #[test]
225 fn qs_map_iter() {
226 let d = vec![
227 ([ez_term(":a"), ez_term(":b"), ez_term(":c")], None),
228 ([ez_term(":d"), ez_term(":e"), ez_term(":f")], None),
229 ([ez_term(":g"), ez_term(":h"), ez_term(":i")], None),
230 ];
231 let h: Result<Vec<String>, _> = d
232 .quads()
233 .map_quads(|q| q.s().iri().unwrap().to_string())
234 .into_iter()
235 .collect();
236 assert_eq!(
237 h.unwrap(),
238 vec![
239 "tag:a".to_string(),
240 "tag:d".to_string(),
241 "tag:g".to_string(),
242 ]
243 )
244 }
245}