Skip to content

Commit a5b457d

Browse files
committed
impl DoubleEndedIterator for ExactlyOneError
1 parent 9f09297 commit a5b457d

2 files changed

Lines changed: 32 additions & 3 deletions

File tree

src/exactly_one_err.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use std::error::Error;
33
use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
44

5-
use std::iter::ExactSizeIterator;
5+
use std::iter::{ExactSizeIterator, Fuse};
66

77
use either::Either;
88

@@ -24,7 +24,7 @@ where
2424
I: Iterator,
2525
{
2626
first_two: Option<Either<[I::Item; 2], I::Item>>,
27-
inner: I,
27+
inner: Fuse<I>,
2828
}
2929

3030
impl<I> ExactlyOneError<I>
@@ -33,7 +33,10 @@ where
3333
{
3434
/// Creates a new `ExactlyOneErr` iterator.
3535
pub(crate) fn new(first_two: Option<Either<[I::Item; 2], I::Item>>, inner: I) -> Self {
36-
Self { first_two, inner }
36+
Self {
37+
first_two,
38+
inner: inner.fuse(),
39+
}
3740
}
3841

3942
fn additional_len(&self) -> usize {
@@ -91,6 +94,22 @@ where
9194

9295
impl<I> ExactSizeIterator for ExactlyOneError<I> where I: ExactSizeIterator {}
9396

97+
impl<I: DoubleEndedIterator> DoubleEndedIterator for ExactlyOneError<I> {
98+
fn next_back(&mut self) -> Option<Self::Item> {
99+
if let Some(next) = self.inner.next_back() {
100+
return Some(next);
101+
};
102+
match self.first_two.take() {
103+
Some(Either::Left([first, second])) => {
104+
self.first_two = Some(Either::Right(first));
105+
Some(second)
106+
}
107+
Some(Either::Right(second)) => Some(second),
108+
None => None,
109+
}
110+
}
111+
}
112+
94113
impl<I> Display for ExactlyOneError<I>
95114
where
96115
I: Iterator,

tests/quick.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,6 +1512,16 @@ quickcheck! {
15121512
}
15131513
}
15141514

1515+
quickcheck! {
1516+
fn exactly_one_double_ended(a: Vec<i32>) -> TestResult {
1517+
let ret = a.iter().copied().exactly_one();
1518+
match a.len() {
1519+
1 => TestResult::passed(),
1520+
_ => TestResult::from_bool(a.iter().rev().copied().eq(ret.unwrap_err().rev())),
1521+
}
1522+
}
1523+
}
1524+
15151525
quickcheck! {
15161526
fn at_most_one_i32(a: Vec<i32>) -> TestResult {
15171527
let ret = a.iter().cloned().at_most_one();

0 commit comments

Comments
 (0)