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