use std::{ fmt::Debug, marker::PhantomData, ops::{Index, IndexMut}, }; // I had an idea for why these were different... now I don't pub type Size = u32; pub type Len = u32; pub struct ID(pub usize, PhantomData); impl ID { pub fn new(i: usize) -> Self { Self(i, PhantomData) } } impl From for ID { fn from(value: usize) -> Self { Self(value, PhantomData) } } impl Debug for ID { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{{{}}}", self.0) } } impl PartialEq for ID { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } impl Eq for ID {} impl std::hash::Hash for ID { fn hash(&self, state: &mut H) { self.0.hash(state); } } impl Clone for ID { fn clone(&self) -> Self { Self(self.0.clone(), PhantomData) } } impl Copy for ID {} // :fear: impl Index> for Vec { type Output = T; fn index(&self, i: ID) -> &Self::Output { &self[i.0] } } impl IndexMut> for Vec { fn index_mut(&mut self, i: ID) -> &mut Self::Output { &mut self[i.0] } } impl Index<&ID> for Vec { type Output = T; fn index(&self, i: &ID) -> &Self::Output { &self[i.0] } } impl IndexMut<&ID> for Vec { fn index_mut(&mut self, i: &ID) -> &mut Self::Output { &mut self[i.0] } } impl Index<&mut ID> for Vec { type Output = T; fn index(&self, i: &mut ID) -> &Self::Output { &self[i.0] } } impl IndexMut<&mut ID> for Vec { fn index_mut(&mut self, i: &mut ID) -> &mut Self::Output { &mut self[i.0] } } impl Index> for [T] { type Output = T; fn index(&self, i: ID) -> &Self::Output { &self[i.0] } } impl IndexMut> for [T] { fn index_mut(&mut self, i: ID) -> &mut Self::Output { &mut self[i.0] } } impl Index<&ID> for [T] { type Output = T; fn index(&self, i: &ID) -> &Self::Output { &self[i.0] } } impl IndexMut<&ID> for [T] { fn index_mut(&mut self, i: &ID) -> &mut Self::Output { &mut self[i.0] } } impl Index<&mut ID> for [T] { type Output = T; fn index(&self, i: &mut ID) -> &Self::Output { &self[i.0] } } impl IndexMut<&mut ID> for [T] { fn index_mut(&mut self, i: &mut ID) -> &mut Self::Output { &mut self[i.0] } }