]> git.proxmox.com Git - rustc.git/blob - vendor/itertools-0.8.2/src/exactly_one_err.rs
New upstream version 1.52.1+dfsg1
[rustc.git] / vendor / itertools-0.8.2 / src / exactly_one_err.rs
1 use std::iter::ExactSizeIterator;
2
3 use 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)]
14 pub struct ExactlyOneError<I>
15 where
16 I: Iterator,
17 {
18 first_two: (Option<I::Item>, Option<I::Item>),
19 inner: I,
20 }
21
22 impl<I> ExactlyOneError<I>
23 where
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
32 impl<I> Iterator for ExactlyOneError<I>
33 where
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
58 impl<I> ExactSizeIterator for ExactlyOneError<I> where I: ExactSizeIterator {}