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