1 use core::iter::FusedIterator;
2 
3 use super::Chunk;
4 use crate::types::ChunkLength;
5 
6 /// A consuming iterator over the elements of a `Chunk`.
7 pub struct Iter<A, N>
8 where
9     N: ChunkLength<A>,
10 {
11     pub(crate) chunk: Chunk<A, N>,
12 }
13 
14 impl<A, N> Iterator for Iter<A, N>
15 where
16     N: ChunkLength<A>,
17 {
18     type Item = A;
next(&mut self) -> Option<Self::Item>19     fn next(&mut self) -> Option<Self::Item> {
20         if self.chunk.is_empty() {
21             None
22         } else {
23             Some(self.chunk.pop_front())
24         }
25     }
26 
size_hint(&self) -> (usize, Option<usize>)27     fn size_hint(&self) -> (usize, Option<usize>) {
28         (self.chunk.len(), Some(self.chunk.len()))
29     }
30 }
31 
32 impl<A, N> DoubleEndedIterator for Iter<A, N>
33 where
34     N: ChunkLength<A>,
35 {
next_back(&mut self) -> Option<Self::Item>36     fn next_back(&mut self) -> Option<Self::Item> {
37         if self.chunk.is_empty() {
38             None
39         } else {
40             Some(self.chunk.pop_back())
41         }
42     }
43 }
44 
45 impl<A, N> ExactSizeIterator for Iter<A, N> where N: ChunkLength<A> {}
46 
47 impl<A, N> FusedIterator for Iter<A, N> where N: ChunkLength<A> {}
48 
49 /// A draining iterator over the elements of a `Chunk`.
50 ///
51 /// "Draining" means that as the iterator yields each element, it's removed from
52 /// the `Chunk`. When the iterator terminates, the chunk will be empty. This is
53 /// different from the consuming iterator `Iter` in that `Iter` will take
54 /// ownership of the `Chunk` and discard it when you're done iterating, while
55 /// `Drain` leaves you still owning the drained `Chunk`.
56 pub struct Drain<'a, A, N>
57 where
58     N: ChunkLength<A>,
59 {
60     pub(crate) chunk: &'a mut Chunk<A, N>,
61 }
62 
63 impl<'a, A, N> Iterator for Drain<'a, A, N>
64 where
65     A: 'a,
66     N: ChunkLength<A> + 'a,
67 {
68     type Item = A;
69 
next(&mut self) -> Option<Self::Item>70     fn next(&mut self) -> Option<Self::Item> {
71         if self.chunk.is_empty() {
72             None
73         } else {
74             Some(self.chunk.pop_front())
75         }
76     }
77 
size_hint(&self) -> (usize, Option<usize>)78     fn size_hint(&self) -> (usize, Option<usize>) {
79         (self.chunk.len(), Some(self.chunk.len()))
80     }
81 }
82 
83 impl<'a, A, N> DoubleEndedIterator for Drain<'a, A, N>
84 where
85     A: 'a,
86     N: ChunkLength<A> + 'a,
87 {
next_back(&mut self) -> Option<Self::Item>88     fn next_back(&mut self) -> Option<Self::Item> {
89         if self.chunk.is_empty() {
90             None
91         } else {
92             Some(self.chunk.pop_back())
93         }
94     }
95 }
96 
97 impl<'a, A, N> ExactSizeIterator for Drain<'a, A, N>
98 where
99     A: 'a,
100     N: ChunkLength<A> + 'a,
101 {
102 }
103 
104 impl<'a, A, N> FusedIterator for Drain<'a, A, N>
105 where
106     A: 'a,
107     N: ChunkLength<A> + 'a,
108 {
109 }
110