use std::{ fmt, hash, ops::{Index, IndexMut}, cmp::{PartialEq, Eq}, marker::PhantomData, }; pub struct Id(usize, PhantomData); impl Id { pub fn id(&self) -> usize { self.0 } } impl Copy for Id {} impl Clone for Id { fn clone(&self) -> Self { Self(self.0, PhantomData) } } impl Eq for Id {} impl PartialEq for Id { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } impl fmt::Debug for Id { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Id<{}>({})", std::any::type_name::(), self.0) } } impl hash::Hash for Id { fn hash(&self, h: &mut H) { self.0.hash(h); } } pub struct Store { items: Vec, } impl Default for Store { fn default() -> Self { Self { items: Vec::new() } } } impl Store { pub fn get(&self, id: Id) -> &T { self.items.get(id.0).unwrap() } pub fn get_mut(&mut self, id: Id) -> &mut T { self.items.get_mut(id.0).unwrap() } pub fn ids(&self) -> impl Iterator> { (0..self.items.len()).map(|i| Id(i, PhantomData)) } pub fn iter(&self) -> impl Iterator { self.items.iter() } pub fn iter_mut(&mut self) -> impl Iterator { self.items.iter_mut() } pub fn iter_ids(&self) -> impl Iterator, &T)> { self .items .iter() .enumerate() .map(|(i, item)| (Id(i, PhantomData), item)) } pub fn insert(&mut self, item: T) -> Id { let id = Id(self.items.len(), PhantomData); self.items.push(item); id } } impl Index> for Store { type Output = T; fn index(&self, id: Id) -> &Self::Output { self.get(id) } } impl IndexMut> for Store { fn index_mut(&mut self, id: Id) -> &mut Self::Output { self.get_mut(id) } }