Skip to content

Commit a796eed

Browse files
authored
Add iter::reverse_if helper (#838)
* Add iter::reverse_if helper * Changelog
1 parent 4d98a29 commit a796eed

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

crates/stackable-operator/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
### Added
8+
9+
- `iter::reverse_if` helper ([#838]).
10+
11+
[#838]: https://github.com/stackabletech/operator-rs/pull/838
12+
713
## [0.73.0] - 2024-08-09
814

915
### Added

crates/stackable-operator/src/iter.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,51 @@
11
//! Extensions for use cases that [`Iterator`] doesn't handle natively quite yet
22
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+
349
/// Fallible version of [`Iterator::flatten`]
450
///
551
/// If the outer [`Iterator`] returns [`Ok`] then each item in the inner iterator is emitted,
@@ -61,6 +107,19 @@ pub trait TryFromIterator<T>: Sized {
61107
mod tests {
62108
use super::*;
63109

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+
64123
#[test]
65124
fn try_flatten_marble_test() {
66125
let stream = vec![

0 commit comments

Comments
 (0)