/home/runner/work/bare_err_tree/bare_err_tree/bare_err_tree/src/buffer.rs
Line | Count | Source |
1 | | /* |
2 | | * This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at https://mozilla.org/MPL/2.0/. |
5 | | */ |
6 | | |
7 | | use core::iter::FusedIterator; |
8 | | |
9 | | /// Stores the most recent item. |
10 | | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
11 | | pub struct IterBuffer<I: Iterator> { |
12 | | iter: I, |
13 | | buffer: Option<I::Item>, |
14 | | } |
15 | | |
16 | | impl<I> From<I> for IterBuffer<I> |
17 | | where |
18 | | I: Iterator, |
19 | | { |
20 | 12 | fn from(value: I) -> Self { |
21 | 12 | Self { |
22 | 12 | iter: value, |
23 | 12 | buffer: None, |
24 | 12 | } |
25 | 12 | } |
26 | | } |
27 | | |
28 | | impl<I> Iterator for IterBuffer<I> |
29 | | where |
30 | | I: Iterator<Item: Clone>, |
31 | | { |
32 | | type Item = I::Item; |
33 | | |
34 | 25 | fn next(&mut self) -> Option<Self::Item> { |
35 | 25 | self.buffer11 = Some(self.iter.next()?14 ); |
36 | 11 | self.buffer.clone() |
37 | 25 | } |
38 | | } |
39 | | |
40 | | impl<I> FusedIterator for IterBuffer<I> where I: Iterator<Item: Clone> + FusedIterator {} |
41 | | |
42 | | impl<I> ExactSizeIterator for IterBuffer<I> |
43 | | where |
44 | | I: Iterator<Item: Clone> + ExactSizeIterator, |
45 | | { |
46 | 0 | fn len(&self) -> usize { |
47 | 0 | self.iter.len() |
48 | 0 | } |
49 | | } |
50 | | |
51 | | impl<I> IterBuffer<I> |
52 | | where |
53 | | I: Iterator, |
54 | | { |
55 | | /// Returns the stored last value, if any, and voids it. |
56 | 11 | pub fn take_stored(&mut self) -> Option<I::Item> { |
57 | 11 | self.buffer.take() |
58 | 11 | } |
59 | | |
60 | | #[allow(dead_code)] |
61 | 0 | pub fn is_empty(&mut self) -> bool { |
62 | 0 | if self.buffer.is_some() { |
63 | 0 | false |
64 | 0 | } else if let Some(val) = self.iter.next() { |
65 | 0 | self.buffer = Some(val); |
66 | 0 | false |
67 | | } else { |
68 | 0 | true |
69 | | } |
70 | 0 | } |
71 | | } |
72 | | |
73 | | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
74 | | pub enum OneOrTwo<T> { |
75 | | One([T; 1]), |
76 | | Two([T; 2]), |
77 | | } |
78 | | |
79 | | impl<T> OneOrTwo<T> { |
80 | 2 | pub fn as_slice(&self) -> &[T] { |
81 | 2 | match self { |
82 | 2 | Self::One(x) => x.as_slice(), |
83 | 0 | Self::Two(x) => x.as_slice(), |
84 | | } |
85 | 2 | } |
86 | | } |
87 | | |
88 | | impl<I> IterBuffer<I> |
89 | | where |
90 | | I: Iterator<Item: Clone>, |
91 | | { |
92 | | /// Combines [`Iterator::next`] and [`Self::take_stored`]. |
93 | | /// |
94 | | /// Only returns a value if there is a next value from the iterator. |
95 | 11 | pub fn take_stored_and_next(&mut self) -> Option<OneOrTwo<I::Item>> { |
96 | 11 | let next_val2 = self.iter.next()?9 ; |
97 | | |
98 | 2 | if let Some(buf_val0 ) = self.buffer.replace(next_val.clone()) { |
99 | 0 | Some(OneOrTwo::Two([buf_val, next_val])) |
100 | | } else { |
101 | 2 | Some(OneOrTwo::One([next_val])) |
102 | | } |
103 | 11 | } |
104 | | } |