Skip to content

Commit a5ae86c

Browse files
committed
impl DoubleEndedIterator for ExactlyOneError
1 parent 50d01b4 commit a5ae86c

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

@@ -22,7 +22,7 @@ where
2222
I: Iterator,
2323
{
2424
first_two: Option<Either<[I::Item; 2], I::Item>>,
25-
inner: I,
25+
inner: Fuse<I>,
2626
}
2727

2828
impl<I> ExactlyOneError<I>
@@ -31,7 +31,10 @@ where
3131
{
3232
/// Creates a new `ExactlyOneErr` iterator.
3333
pub(crate) fn new(first_two: Option<Either<[I::Item; 2], I::Item>>, inner: I) -> Self {
34-
Self { first_two, inner }
34+
Self {
35+
first_two,
36+
inner: inner.fuse(),
37+
}
3538
}
3639

3740
fn additional_len(&self) -> usize {
@@ -89,6 +92,22 @@ where
8992

9093
impl<I> ExactSizeIterator for ExactlyOneError<I> where I: ExactSizeIterator {}
9194

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

tests/quick.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,6 +1400,16 @@ quickcheck! {
14001400
}
14011401
}
14021402

1403+
quickcheck! {
1404+
fn exactly_one_double_ended(a: Vec<i32>) -> TestResult {
1405+
let ret = a.iter().copied().exactly_one();
1406+
match a.len() {
1407+
1 => TestResult::passed(),
1408+
_ => TestResult::from_bool(a.iter().rev().copied().eq(ret.unwrap_err().rev())),
1409+
}
1410+
}
1411+
}
1412+
14031413
quickcheck! {
14041414
fn at_most_one_i32(a: Vec<i32>) -> TestResult {
14051415
let ret = a.iter().cloned().at_most_one();

0 commit comments

Comments
 (0)