|
1 | 1 | //! Extensions for use cases that [`Iterator`] doesn't handle natively quite yet
|
2 | 2 |
|
| 3 | +use std::iter::Rev; |
| 4 | + |
| 5 | +/// Either an `A` or `B`, and forwards all iterator methods accordingly. |
| 6 | +pub enum Either<A, B> { |
| 7 | + Left(A), |
| 8 | + Right(B), |
| 9 | +} |
| 10 | + |
| 11 | +impl<A, B> Iterator for Either<A, B> |
| 12 | +where |
| 13 | + A: Iterator, |
| 14 | + B: Iterator<Item = A::Item>, |
| 15 | +{ |
| 16 | + type Item = A::Item; |
| 17 | + |
| 18 | + fn next(&mut self) -> Option<Self::Item> { |
| 19 | + match self { |
| 20 | + Self::Left(left) => left.next(), |
| 21 | + Self::Right(right) => right.next(), |
| 22 | + } |
| 23 | + } |
| 24 | +} |
| 25 | + |
| 26 | +impl<A, B> DoubleEndedIterator for Either<A, B> |
| 27 | +where |
| 28 | + Self: Iterator, |
| 29 | + A: DoubleEndedIterator<Item = Self::Item>, |
| 30 | + B: DoubleEndedIterator<Item = Self::Item>, |
| 31 | +{ |
| 32 | + fn next_back(&mut self) -> Option<Self::Item> { |
| 33 | + match self { |
| 34 | + Self::Left(left) => left.next_back(), |
| 35 | + Self::Right(right) => right.next_back(), |
| 36 | + } |
| 37 | + } |
| 38 | +} |
| 39 | + |
| 40 | +/// Returns a reversed version of `iter` if `cond` is `true`, otherwise returns it as-is. |
| 41 | +pub fn reverse_if<I: DoubleEndedIterator>(cond: bool, iter: I) -> Either<I, Rev<I>> { |
| 42 | + if cond { |
| 43 | + Either::Right(iter.rev()) |
| 44 | + } else { |
| 45 | + Either::Left(iter) |
| 46 | + } |
| 47 | +} |
| 48 | + |
3 | 49 | /// Fallible version of [`Iterator::flatten`]
|
4 | 50 | ///
|
5 | 51 | /// If the outer [`Iterator`] returns [`Ok`] then each item in the inner iterator is emitted,
|
@@ -61,6 +107,19 @@ pub trait TryFromIterator<T>: Sized {
|
61 | 107 | mod tests {
|
62 | 108 | use super::*;
|
63 | 109 |
|
| 110 | + #[test] |
| 111 | + fn reverse_if_marble_test() { |
| 112 | + let values = [0, 1, 2, 3]; |
| 113 | + assert_eq!( |
| 114 | + reverse_if(false, values.iter()).collect::<Vec<_>>(), |
| 115 | + [&0, &1, &2, &3] |
| 116 | + ); |
| 117 | + assert_eq!( |
| 118 | + reverse_if(true, values.iter()).collect::<Vec<_>>(), |
| 119 | + [&3, &2, &1, &0] |
| 120 | + ); |
| 121 | + } |
| 122 | + |
64 | 123 | #[test]
|
65 | 124 | fn try_flatten_marble_test() {
|
66 | 125 | let stream = vec![
|
|
0 commit comments