1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
use crate::{Headers, Row, RowStream, RowResult}; pub struct FilterRow<I, F> { iter: I, f: F, headers: Headers, } impl<I, F> FilterRow<I, F> where I: RowStream, F: Fn(&Headers, &Row) -> bool, { pub fn new( iter: I, f: F, ) -> FilterRow<I, F> { let headers = iter.headers().clone(); FilterRow { iter, f, headers, } } } pub struct IntoIter<I, F> { iter: I, f: F, headers: Headers, } impl<I, F> Iterator for IntoIter<I, F> where I: Iterator<Item = RowResult>, F: Fn(&Headers, &Row) -> bool, { type Item = RowResult; fn next(&mut self) -> Option<Self::Item> { while let Some(rs) = self.iter.next() { match rs { Ok(row) => if (self.f)(&self.headers, &row) { return Some(Ok(row)); } Err(e) => return Some(Err(e)), } } None } } impl<I, F> IntoIterator for FilterRow<I, F> where I: RowStream, F: Fn(&Headers, &Row) -> bool, { type Item = RowResult; type IntoIter = IntoIter<I::IntoIter, F>; fn into_iter(self) -> Self::IntoIter { Self::IntoIter { iter: self.iter.into_iter(), f: self.f, headers: self.headers, } } } impl<I, F> RowStream for FilterRow<I, F> where I: RowStream, F: Fn(&Headers, &Row) -> bool, { fn headers(&self) -> &Headers { &self.headers } } #[cfg(test)] mod tests { use super::FilterRow; use crate::{Row, MockStream, error}; #[test] fn test_filter() { let iter = MockStream::from_rows( vec![ Ok(Row::from(vec!["a", "b"])), Ok(Row::from(vec!["1", "2"])), Ok(Row::from(vec!["2", "7"])), Err(error::Error::InconsistentHeaders), Ok(Row::from(vec!["1", "1"])), Ok(Row::from(vec!["2", "9"])), ] .into_iter(), ) .unwrap(); let mut r = FilterRow::new(iter, |headers, row| { headers.get_field(row, "b").unwrap().parse::<i32>().unwrap() > 2 }) .into_iter(); assert!(r.next().unwrap().is_ok()); assert!(r.next().unwrap().is_err()); assert!(r.next().unwrap().is_ok()); assert!(r.next().is_none()); } }