1use std::fmt::{self, Debug};
49use std::marker::PhantomData;
50use std::ops::{Index, IndexMut};
51
52use crate::entity::{Entity, EntityId};
53
54#[derive(Clone, PartialEq, Eq, Hash)]
58pub struct EntityVec<E: Entity, V> {
59 data: Vec<V>,
60 _phantom: PhantomData<E>,
61}
62
63impl<E: Entity, V> EntityVec<E, V> {
64 pub fn new() -> Self {
66 Self {
67 data: Vec::new(),
68 _phantom: PhantomData,
69 }
70 }
71
72 pub fn with_capacity(capacity: usize) -> Self {
74 Self {
75 data: Vec::with_capacity(capacity),
76 _phantom: PhantomData,
77 }
78 }
79
80 #[inline]
82 pub fn len(&self) -> usize {
83 self.data.len()
84 }
85
86 #[inline]
88 pub fn capacity(&self) -> usize {
89 self.data.capacity()
90 }
91
92 #[inline]
94 pub fn is_empty(&self) -> bool {
95 self.data.is_empty()
96 }
97
98 pub fn reserve(&mut self, additional: usize) {
100 self.data.reserve(additional);
101 }
102
103 pub fn shrink_to_fit(&mut self) {
105 self.data.shrink_to_fit();
106 }
107
108 pub fn push(&mut self, value: V) {
110 self.data.push(value);
111 }
112
113 pub fn pop(&mut self) -> Option<V> {
115 self.data.pop()
116 }
117
118 pub fn get(&self, entity_id: EntityId<E>) -> Option<&V> {
120 self.data.get(entity_id.0)
121 }
122
123 pub fn get_mut(&mut self, entity_id: EntityId<E>) -> Option<&mut V> {
125 self.data.get_mut(entity_id.0)
126 }
127
128 pub fn last(&self) -> Option<&V> {
130 self.data.last()
131 }
132
133 pub fn last_mut(&mut self) -> Option<&mut V> {
135 self.data.last_mut()
136 }
137
138 pub fn as_slice(&self) -> &[V] {
140 &self.data
141 }
142
143 pub fn as_mut_slice(&mut self) -> &mut [V] {
145 &mut self.data
146 }
147
148 pub fn iter(&self) -> std::slice::Iter<'_, V> {
150 self.data.iter()
151 }
152
153 pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, V> {
155 self.data.iter_mut()
156 }
157
158 pub fn clear(&mut self) {
160 self.data.clear();
161 }
162
163 pub fn truncate(&mut self, len: usize) {
165 self.data.truncate(len);
166 }
167
168 pub fn extend<I>(&mut self, iter: I)
170 where
171 I: IntoIterator<Item = V>,
172 {
173 self.data.extend(iter);
174 }
175
176 pub fn resize(&mut self, new_len: usize, value: V)
178 where
179 V: Clone,
180 {
181 self.data.resize(new_len, value);
182 }
183
184 pub fn resize_with<F>(&mut self, new_len: usize, f: F)
186 where
187 F: FnMut() -> V,
188 {
189 self.data.resize_with(new_len, f);
190 }
191
192 pub fn contains(&self, value: &V) -> bool
194 where
195 V: PartialEq,
196 {
197 self.data.contains(value)
198 }
199
200 pub fn into_vec(self) -> Vec<V> {
202 self.data
203 }
204}
205
206impl<E: Entity, V> Default for EntityVec<E, V> {
207 fn default() -> Self {
208 Self::new()
209 }
210}
211
212impl<E: Entity, V: Debug> Debug for EntityVec<E, V> {
213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214 self.data.fmt(f)
215 }
216}
217
218impl<E: Entity, V> From<Vec<V>> for EntityVec<E, V> {
219 fn from(data: Vec<V>) -> Self {
220 Self {
221 data,
222 _phantom: PhantomData,
223 }
224 }
225}
226
227impl<E: Entity, V> From<EntityVec<E, V>> for Vec<V> {
228 fn from(value: EntityVec<E, V>) -> Self {
229 value.data
230 }
231}
232
233impl<E: Entity, V> FromIterator<V> for EntityVec<E, V> {
234 fn from_iter<I: IntoIterator<Item = V>>(iter: I) -> Self {
235 Self::from(Vec::from_iter(iter))
236 }
237}
238
239impl<E: Entity, V> Extend<V> for EntityVec<E, V> {
240 fn extend<I: IntoIterator<Item = V>>(&mut self, iter: I) {
241 self.data.extend(iter);
242 }
243}
244
245impl<E: Entity, V> Index<EntityId<E>> for EntityVec<E, V> {
246 type Output = V;
247
248 fn index(&self, index: EntityId<E>) -> &Self::Output {
249 &self.data[index.0]
250 }
251}
252
253impl<E: Entity, V> IndexMut<EntityId<E>> for EntityVec<E, V> {
254 fn index_mut(&mut self, index: EntityId<E>) -> &mut Self::Output {
255 &mut self.data[index.0]
256 }
257}
258
259impl<E: Entity, V> IntoIterator for EntityVec<E, V> {
260 type Item = V;
261 type IntoIter = std::vec::IntoIter<V>;
262
263 fn into_iter(self) -> Self::IntoIter {
264 self.data.into_iter()
265 }
266}
267
268impl<'a, E: Entity, V> IntoIterator for &'a EntityVec<E, V> {
269 type Item = &'a V;
270 type IntoIter = std::slice::Iter<'a, V>;
271
272 fn into_iter(self) -> Self::IntoIter {
273 self.iter()
274 }
275}
276
277impl<'a, E: Entity, V> IntoIterator for &'a mut EntityVec<E, V> {
278 type Item = &'a mut V;
279 type IntoIter = std::slice::IterMut<'a, V>;
280
281 fn into_iter(self) -> Self::IntoIter {
282 self.iter_mut()
283 }
284}
285
286#[cfg(test)]
287mod tests {
288 use super::EntityVec;
289 use crate::define_entity;
290 use crate::entity::EntityId;
291
292 define_entity!(TestEntity);
293 #[test]
294 fn new_is_empty() {
295 let vec = EntityVec::<TestEntity, i32>::new();
296 assert_eq!(vec.len(), 0);
297 assert!(vec.is_empty());
298 assert_eq!(vec.capacity(), 0);
299 }
300
301 #[test]
302 fn with_capacity_sets_initial_capacity() {
303 let vec = EntityVec::<TestEntity, i32>::with_capacity(8);
304 assert_eq!(vec.len(), 0);
305 assert!(vec.capacity() >= 8);
306 }
307
308 #[test]
309 fn push_appends_values_in_order() {
310 let mut vec = EntityVec::<TestEntity, &'static str>::new();
311 vec.push("zero");
312 vec.push("one");
313 vec.push("two");
314
315 assert_eq!(vec.len(), 3);
316 assert_eq!(vec[EntityId::new(0)], "zero");
317 assert_eq!(vec[EntityId::new(1)], "one");
318 assert_eq!(vec[EntityId::new(2)], "two");
319 }
320
321 #[test]
322 fn get_and_get_mut_are_bounds_checked() {
323 let mut vec = EntityVec::<TestEntity, i32>::new();
324 vec.push(10);
325 vec.push(20);
326 let id0 = EntityId::new(0);
327 let id1 = EntityId::new(1);
328
329 assert_eq!(vec.get(id0), Some(&10));
330 assert_eq!(vec.get(id1), Some(&20));
331 assert_eq!(vec.get(EntityId::new(2)), None);
332
333 *vec.get_mut(id1).unwrap() = 99;
334 assert_eq!(vec.get(id1), Some(&99));
335 assert_eq!(vec.get_mut(EntityId::new(2)), None);
336 }
337
338 #[test]
339 fn index_and_index_mut_use_entity_ids() {
340 let mut vec = EntityVec::<TestEntity, i32>::new();
341 vec.push(1);
342 vec.push(2);
343 let id0 = EntityId::new(0);
344 let id1 = EntityId::new(1);
345
346 vec[id1] = 7;
347
348 assert_eq!(vec[id0], 1);
349 assert_eq!(vec[id1], 7);
350 }
351
352 #[test]
353 fn pop_last_last_mut_and_clear_work() {
354 let mut vec = EntityVec::<TestEntity, String>::new();
355 vec.push(String::from("a"));
356 vec.push(String::from("b"));
357
358 assert_eq!(vec.last().map(String::as_str), Some("b"));
359 vec.last_mut().unwrap().push('!');
360 assert_eq!(vec.last().map(String::as_str), Some("b!"));
361 assert_eq!(vec.pop(), Some(String::from("b!")));
362 assert_eq!(vec.pop(), Some(String::from("a")));
363 assert_eq!(vec.pop(), None);
364
365 vec.push(String::from("c"));
366 vec.clear();
367 assert!(vec.is_empty());
368 assert_eq!(vec.last(), None);
369 assert_eq!(vec.last_mut(), None);
370 }
371
372 #[test]
373 fn reserve_and_shrink_to_fit_forward_to_backing_vec() {
374 let mut vec = EntityVec::<TestEntity, i32>::new();
375 vec.reserve(16);
376 assert!(vec.capacity() >= 16);
377
378 vec.extend(0..4);
379 vec.shrink_to_fit();
380 assert!(vec.capacity() >= vec.len());
381 }
382
383 #[test]
384 fn as_slice_and_as_mut_slice_expose_backing_storage() {
385 let mut vec = EntityVec::<TestEntity, i32>::from(vec![1, 2, 3]);
386 assert_eq!(vec.as_slice(), &[1, 2, 3]);
387
388 vec.as_mut_slice()[1] = 9;
389 assert_eq!(vec.as_slice(), &[1, 9, 3]);
390 }
391
392 #[test]
393 fn iter_and_iter_mut_visit_values_in_order() {
394 let mut vec = EntityVec::<TestEntity, i32>::from(vec![1, 2, 3]);
395 let values: Vec<_> = vec.iter().copied().collect();
396 assert_eq!(values, vec![1, 2, 3]);
397
398 for value in vec.iter_mut() {
399 *value *= 2;
400 }
401
402 assert_eq!(vec.as_slice(), &[2, 4, 6]);
403 }
404
405 #[test]
406 fn truncate_removes_trailing_items() {
407 let mut vec = EntityVec::<TestEntity, i32>::from(vec![1, 2, 3, 4]);
408 vec.truncate(2);
409
410 assert_eq!(vec.len(), 2);
411 assert_eq!(vec.get(EntityId::new(0)), Some(&1));
412 assert_eq!(vec.get(EntityId::new(1)), Some(&2));
413 assert_eq!(vec.get(EntityId::new(2)), None);
414 }
415
416 #[test]
417 fn contains_checks_values() {
418 let vec = EntityVec::<TestEntity, i32>::from(vec![3, 5, 8]);
419 assert!(vec.contains(&5));
420 assert!(!vec.contains(&13));
421 }
422
423 #[test]
424 fn from_iter_and_inherent_extend_append_in_order() {
425 let mut vec: EntityVec<TestEntity, i32> = [1, 2].into_iter().collect();
426 EntityVec::extend(&mut vec, [3, 4]);
427
428 assert_eq!(vec.as_slice(), &[1, 2, 3, 4]);
429 vec.push(5);
430 assert_eq!(vec[EntityId::new(4)], 5);
431 }
432
433 #[test]
434 fn trait_extend_appends_values() {
435 let mut vec = EntityVec::<TestEntity, i32>::new();
436 <EntityVec<TestEntity, i32> as Extend<i32>>::extend(&mut vec, [7, 8, 9]);
437 assert_eq!(vec.as_slice(), &[7, 8, 9]);
438 }
439
440 #[test]
441 fn into_vec_and_from_vec_round_trip() {
442 let vec = EntityVec::<TestEntity, i32>::from(vec![4, 5, 6]);
443 let raw = vec.into_vec();
444 assert_eq!(raw, vec![4, 5, 6]);
445
446 let wrapped = EntityVec::<TestEntity, i32>::from(raw.clone());
447 let round_trip: Vec<_> = wrapped.into();
448 assert_eq!(round_trip, raw);
449 }
450
451 #[test]
452 fn into_iterator_variants_match_backing_vec_order() {
453 let mut vec = EntityVec::<TestEntity, i32>::from(vec![1, 2, 3]);
454
455 let shared: Vec<_> = (&vec).into_iter().copied().collect();
456 assert_eq!(shared, vec![1, 2, 3]);
457
458 for value in &mut vec {
459 *value += 10;
460 }
461 assert_eq!(vec.as_slice(), &[11, 12, 13]);
462
463 let owned: Vec<_> = vec.into_iter().collect();
464 assert_eq!(owned, vec![11, 12, 13]);
465 }
466
467 #[test]
468 fn debug_delegates_to_backing_vec() {
469 let vec = EntityVec::<TestEntity, i32>::from(vec![1, 2, 3]);
470 assert_eq!(format!("{vec:?}"), "[1, 2, 3]");
471 }
472
473 #[test]
474 fn clone_and_eq_compare_stored_values() {
475 let vec = EntityVec::<TestEntity, i32>::from(vec![1, 2, 3]);
476 let clone = vec.clone();
477
478 assert_eq!(vec, clone);
479 assert_ne!(vec, EntityVec::<TestEntity, i32>::from(vec![1, 2]));
480 }
481
482 #[test]
483 fn resize_and_resize_with_extend_storage_by_index() {
484 let mut vec = EntityVec::<TestEntity, i32>::new();
485 vec.resize(3, 7);
486 assert_eq!(vec.as_slice(), &[7, 7, 7]);
487
488 let mut next = 10;
489 vec.resize_with(5, || {
490 let value = next;
491 next += 1;
492 value
493 });
494
495 assert_eq!(vec.as_slice(), &[7, 7, 7, 10, 11]);
496 }
497}