1use borsh::{BorshDeserialize, BorshSerialize};
2use core::{iter::FusedIterator, ops::Range};
3
4use super::{Vector, ERR_INDEX_OUT_OF_BOUNDS};
5use crate::env;
6
7#[derive(Debug)]
9pub struct Iter<'a, T>
10where
11 T: BorshSerialize + BorshDeserialize,
12{
13 vec: &'a Vector<T>,
15 range: Range<u32>,
17}
18
19impl<'a, T> Iter<'a, T>
20where
21 T: BorshSerialize + BorshDeserialize,
22{
23 pub(super) fn new(vec: &'a Vector<T>) -> Self {
24 Self { vec, range: Range { start: 0, end: vec.len() } }
25 }
26
27 fn remaining(&self) -> usize {
29 self.range.len()
30 }
31}
32
33impl<'a, T> Iterator for Iter<'a, T>
34where
35 T: BorshSerialize + BorshDeserialize,
36{
37 type Item = &'a T;
38
39 fn next(&mut self) -> Option<Self::Item> {
40 <Self as Iterator>::nth(self, 0)
41 }
42
43 fn size_hint(&self) -> (usize, Option<usize>) {
44 let remaining = self.remaining();
45 (remaining, Some(remaining))
46 }
47
48 fn count(self) -> usize {
49 self.remaining()
50 }
51
52 fn nth(&mut self, n: usize) -> Option<Self::Item> {
53 let idx = self.range.nth(n)?;
54 Some(self.vec.get(idx).unwrap_or_else(|| env::panic_str(ERR_INDEX_OUT_OF_BOUNDS)))
55 }
56}
57
58impl<'a, T> ExactSizeIterator for Iter<'a, T> where T: BorshSerialize + BorshDeserialize {}
59impl<'a, T> FusedIterator for Iter<'a, T> where T: BorshSerialize + BorshDeserialize {}
60
61impl<'a, T> DoubleEndedIterator for Iter<'a, T>
62where
63 T: BorshSerialize + BorshDeserialize,
64{
65 fn next_back(&mut self) -> Option<Self::Item> {
66 <Self as DoubleEndedIterator>::nth_back(self, 0)
67 }
68
69 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
70 let idx = self.range.nth_back(n)?;
71 Some(self.vec.get(idx).unwrap_or_else(|| env::panic_str(ERR_INDEX_OUT_OF_BOUNDS)))
72 }
73}
74
75#[derive(Debug)]
77pub struct IterMut<'a, T>
78where
79 T: BorshSerialize + BorshDeserialize,
80{
81 vec: &'a mut Vector<T>,
83 range: Range<u32>,
85}
86
87impl<'a, T> IterMut<'a, T>
88where
89 T: BorshSerialize + BorshDeserialize,
90{
91 pub(crate) fn new(vec: &'a mut Vector<T>) -> Self {
93 let end = vec.len();
94 Self { vec, range: Range { start: 0, end } }
95 }
96
97 fn remaining(&self) -> usize {
99 self.range.len()
100 }
101}
102
103impl<'a, T> IterMut<'a, T>
104where
105 T: BorshSerialize + BorshDeserialize,
106{
107 fn get_mut<'b>(&'b mut self, at: u32) -> Option<&'a mut T> {
108 self.vec.get_mut(at).map(|value| {
109 unsafe { &mut *(value as *mut T) }
114 })
115 }
116}
117
118impl<'a, T> Iterator for IterMut<'a, T>
119where
120 T: BorshSerialize + BorshDeserialize,
121{
122 type Item = &'a mut T;
123
124 fn next(&mut self) -> Option<Self::Item> {
125 <Self as Iterator>::nth(self, 0)
126 }
127
128 fn size_hint(&self) -> (usize, Option<usize>) {
129 let remaining = self.remaining();
130 (remaining, Some(remaining))
131 }
132
133 fn count(self) -> usize {
134 self.remaining()
135 }
136
137 fn nth(&mut self, n: usize) -> Option<Self::Item> {
138 let idx = self.range.nth(n)?;
139 Some(self.get_mut(idx).unwrap_or_else(|| env::panic_str(ERR_INDEX_OUT_OF_BOUNDS)))
140 }
141}
142
143impl<'a, T> ExactSizeIterator for IterMut<'a, T> where T: BorshSerialize + BorshDeserialize {}
144impl<'a, T> FusedIterator for IterMut<'a, T> where T: BorshSerialize + BorshDeserialize {}
145
146impl<'a, T> DoubleEndedIterator for IterMut<'a, T>
147where
148 T: BorshSerialize + BorshDeserialize,
149{
150 fn next_back(&mut self) -> Option<Self::Item> {
151 <Self as DoubleEndedIterator>::nth_back(self, 0)
152 }
153
154 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
155 let idx = self.range.nth_back(n)?;
156 Some(self.get_mut(idx).unwrap_or_else(|| env::panic_str(ERR_INDEX_OUT_OF_BOUNDS)))
157 }
158}
159
160#[derive(Debug)]
162pub struct Drain<'a, T>
163where
164 T: BorshSerialize + BorshDeserialize,
165{
166 vec: &'a mut Vector<T>,
168 range: Range<u32>,
170 delete_range: Range<u32>,
172}
173
174impl<'a, T> Drain<'a, T>
175where
176 T: BorshSerialize + BorshDeserialize,
177{
178 pub(crate) fn new(vec: &'a mut Vector<T>, range: Range<u32>) -> Self {
180 Self { vec, delete_range: range.clone(), range }
181 }
182
183 pub(crate) fn remaining(&self) -> usize {
185 self.range.len()
186 }
187 fn remove(&mut self, index: u32) -> T {
188 self.vec
189 .values
190 .get_mut_inner(index)
191 .replace(None)
192 .unwrap_or_else(|| env::abort())
194 }
195}
196
197impl<'a, T> Drop for Drain<'a, T>
198where
199 T: BorshSerialize + BorshDeserialize,
200{
201 fn drop(&mut self) {
202 let delete_indices = (self.delete_range.start..self.range.start)
203 .chain(self.range.end..self.delete_range.end);
204
205 for i in delete_indices {
207 self.vec.values.set(i, None);
208 }
209
210 let shift_len = self.delete_range.len() as u32;
212 for i in self.delete_range.end..self.vec.len() {
213 self.vec.swap(i, i - shift_len);
214 }
215
216 self.vec.len -= self.delete_range.len() as u32;
218 }
219}
220
221impl<'a, T> Iterator for Drain<'a, T>
222where
223 T: BorshSerialize + BorshDeserialize,
224{
225 type Item = T;
226
227 fn next(&mut self) -> Option<Self::Item> {
228 let delete_idx = self.range.next()?;
230 let prev = self.remove(delete_idx);
231
232 Some(prev)
233 }
234
235 fn nth(&mut self, n: usize) -> Option<Self::Item> {
236 for _ in 0..n {
237 let next = self.range.next()?;
238 self.vec.values.set(next, None);
241 }
242 self.next()
243 }
244
245 fn size_hint(&self) -> (usize, Option<usize>) {
246 let remaining = self.remaining();
247 (remaining, Some(remaining))
248 }
249
250 fn count(self) -> usize {
251 self.remaining()
252 }
253}
254
255impl<'a, T> ExactSizeIterator for Drain<'a, T> where T: BorshSerialize + BorshDeserialize {}
256impl<'a, T> FusedIterator for Drain<'a, T> where T: BorshSerialize + BorshDeserialize {}
257
258impl<'a, T> DoubleEndedIterator for Drain<'a, T>
259where
260 T: BorshSerialize + BorshDeserialize,
261{
262 fn next_back(&mut self) -> Option<Self::Item> {
263 let delete_idx = self.range.next_back()?;
264 let prev = self.remove(delete_idx);
265
266 Some(prev)
267 }
268
269 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
270 for _ in 0..n {
272 let next = self.range.next_back()?;
273 self.vec.values.set(next, None);
276 }
277 self.next_back()
278 }
279}