orx_fixed_vec/
fixed_vec.rs1use alloc::vec::Vec;
2
3pub struct FixedVec<T> {
18 pub(crate) data: Vec<T>,
19}
20
21impl<T> FixedVec<T> {
22 pub fn new(fixed_capacity: usize) -> Self {
37 Self {
38 data: Vec::with_capacity(fixed_capacity),
39 }
40 }
41
42 pub fn into_inner(self) -> Vec<T> {
61 self.data
62 }
63
64 pub fn room(&self) -> usize {
80 self.data.capacity() - self.data.len()
81 }
82
83 pub fn is_full(&self) -> bool {
101 self.data.capacity() == self.data.len()
102 }
103
104 pub fn as_slice(&self) -> &[T] {
108 self.data.as_slice()
109 }
110
111 pub fn as_mut_vec(&mut self) -> &mut Vec<T> {
113 &mut self.data
114 }
115
116 #[inline(always)]
118 pub(crate) fn panic_if_not_enough_room_for(&self, num_new_items: usize) {
119 assert!(
120 self.data.len() + num_new_items <= self.data.capacity(),
121 "{}",
122 ERR_MSG_OUT_OF_ROOM
123 );
124 }
125
126 #[inline(always)]
127 pub(crate) fn push_or_panic(&mut self, value: T) {
128 assert!(
129 self.data.len() < self.data.capacity(),
130 "{}",
131 ERR_MSG_OUT_OF_ROOM
132 );
133 self.data.push(value);
134 }
135}
136
137impl<T> From<Vec<T>> for FixedVec<T> {
138 fn from(data: Vec<T>) -> Self {
139 Self { data }
140 }
141}
142
143impl<T> From<FixedVec<T>> for Vec<T> {
144 fn from(value: FixedVec<T>) -> Self {
145 value.data
146 }
147}
148
149const ERR_MSG_OUT_OF_ROOM: &str =
150 "FixedVec is full, a fixed capacity vector cannot exceed its initial capacity.";
151
152#[cfg(test)]
153mod tests {
154 use alloc::vec;
155 use alloc::vec::Vec;
156
157 use crate::prelude::*;
158
159 #[test]
160 fn new() {
161 let vec: FixedVec<char> = FixedVec::new(17);
162 assert_eq!(0, vec.len());
163 assert!(vec.is_empty());
164 assert_eq!(17, vec.capacity());
165 }
166
167 #[test]
168 fn from() {
169 let vec = vec![1, 3, 42];
170 let fixed_vec: FixedVec<_> = vec.clone().into();
171 assert_eq!(&vec, fixed_vec.as_ref());
172 assert_eq!(vec.len(), fixed_vec.capacity());
173 let into_vec: Vec<_> = fixed_vec.into();
174 assert_eq!(&vec, &into_vec);
175
176 let mut vec = Vec::with_capacity(7);
177 vec.push(42);
178 let fixed_vec: FixedVec<_> = vec.clone().into();
179 assert_eq!(&vec, fixed_vec.as_ref());
180 assert_eq!(1, fixed_vec.capacity());
181 let into_vec: Vec<_> = fixed_vec.into();
182 assert_eq!(&vec, &into_vec);
183 }
184
185 #[test]
186 fn room() {
187 let mut vec = FixedVec::new(10);
188
189 for i in 0..vec.capacity() {
190 assert_eq!(i, vec.len());
191 assert_eq!(vec.capacity() - i, vec.room());
192 vec.push(1.1);
193 }
194
195 assert_eq!(vec.len(), vec.capacity());
196 assert_eq!(0, vec.room());
197 assert!(vec.is_full());
198 }
199
200 #[test]
201 fn as_slice() {
202 let fixed_vec: FixedVec<_> = (0..20).collect();
203 let vec: Vec<_> = (0..20).collect();
204
205 let slice = fixed_vec.as_slice();
206 assert_eq!(slice, &vec);
207 }
208
209 #[test]
210 fn panic_if_not_enough_room_for_when_ok() {
211 let mut vec = FixedVec::new(3);
212
213 vec.panic_if_not_enough_room_for(3);
214
215 vec.push("a");
216 vec.panic_if_not_enough_room_for(2);
217
218 vec.push("b");
219 vec.panic_if_not_enough_room_for(1);
220
221 vec.push("c");
222 vec.panic_if_not_enough_room_for(0);
223 }
224
225 #[test]
226 #[should_panic]
227 fn panic_if_not_enough_room_for_when_not_ok() {
228 let mut vec = FixedVec::new(3);
229 vec.push("a");
230 vec.panic_if_not_enough_room_for(3);
231 }
232
233 #[test]
234 fn push_or_panic_when_ok() {
235 let mut vec = FixedVec::new(3);
236
237 vec.push_or_panic(0);
238 vec.push_or_panic(1);
239 vec.push_or_panic(2);
240
241 assert_eq!(Some(&0), vec.get(0));
242 assert_eq!(Some(&1), vec.get(1));
243 assert_eq!(Some(&2), vec.get(2));
244 }
245 #[test]
246 #[should_panic]
247 fn push_or_panic_when_not_ok() {
248 let mut vec = FixedVec::new(3);
249
250 vec.push_or_panic(0);
251 vec.push_or_panic(1);
252 vec.push_or_panic(2);
253
254 assert_eq!(Some(&0), vec.get(0));
255 assert_eq!(Some(&1), vec.get(1));
256 assert_eq!(Some(&2), vec.get(2));
257
258 vec.push_or_panic(3);
259 }
260}