]> git.proxmox.com Git - rustc.git/blame - vendor/itertools-0.8.2/src/exactly_one_err.rs
New upstream version 1.47.0+dfsg1
[rustc.git] / vendor / itertools-0.8.2 / src / exactly_one_err.rs
CommitLineData
3dfed10e
XL
1use std::iter::ExactSizeIterator;
2
3use size_hint;
4
5/// Iterator returned for the error case of `IterTools::exactly_one()`
6/// This iterator yields exactly the same elements as the input iterator.
7///
8/// During the execution of exactly_one the iterator must be mutated. This wrapper
9/// effectively "restores" the state of the input iterator when it's handed back.
10///
11/// This is very similar to PutBackN except this iterator only supports 0-2 elements and does not
12/// use a `Vec`.
13#[derive(Debug, Clone)]
14pub struct ExactlyOneError<I>
15where
16 I: Iterator,
17{
18 first_two: (Option<I::Item>, Option<I::Item>),
19 inner: I,
20}
21
22impl<I> ExactlyOneError<I>
23where
24 I: Iterator,
25{
26 /// Creates a new `ExactlyOneErr` iterator.
27 pub(crate) fn new(first_two: (Option<I::Item>, Option<I::Item>), inner: I) -> Self {
28 Self { first_two, inner }
29 }
30}
31
32impl<I> Iterator for ExactlyOneError<I>
33where
34 I: Iterator,
35{
36 type Item = I::Item;
37
38 fn next(&mut self) -> Option<Self::Item> {
39 self.first_two
40 .0
41 .take()
42 .or_else(|| self.first_two.1.take())
43 .or_else(|| self.inner.next())
44 }
45
46 fn size_hint(&self) -> (usize, Option<usize>) {
47 let mut additional_len = 0;
48 if self.first_two.0.is_some() {
49 additional_len += 1;
50 }
51 if self.first_two.1.is_some() {
52 additional_len += 1;
53 }
54 size_hint::add_scalar(self.inner.size_hint(), additional_len)
55 }
56}
57
58impl<I> ExactSizeIterator for ExactlyOneError<I> where I: ExactSizeIterator {}