use ecs::util::VecExt; #[derive(Debug)] pub struct MapVec { inner: Vec<(Key, Value)>, } impl MapVec { pub fn insert(&mut self, key: Key, value: Value) { self.inner .insert_at_part_pt_by_key((key, value), |(a_key, _)| a_key); } pub fn remove(&mut self, key: Key) -> Option { let index = self .inner .binary_search_by_key(&&key, |(a_key, _)| a_key) .ok()?; let (_, value) = self.inner.remove(index); Some(value) } pub fn get(&self, key: &Key) -> Option<&Value> { let index = self .inner .binary_search_by_key(&key, |(a_key, _)| a_key) .ok()?; let Some((_, value)) = self.inner.get(index) else { unreachable!(); // Reason: Index from binary search cannot be OOB }; Some(value) } pub fn get_mut(&mut self, key: &Key) -> Option<&mut Value> { let index = self .inner .binary_search_by_key(&key, |(a_key, _)| a_key) .ok()?; let Some((_, value)) = self.inner.get_mut(index) else { unreachable!(); // Reason: Index from binary search cannot be OOB }; Some(value) } pub fn values(&self) -> impl Iterator { self.inner.iter().map(|(_, value)| value) } } impl Default for MapVec { fn default() -> Self { Self { inner: Vec::new() } } } macro_rules! try_option { ($expr: expr) => { match $expr { Ok(value) => value, Err(err) => { return Some(Err(err.into())); } } }; } pub(crate) use try_option; macro_rules! or { (($($tt: tt)+) else ($($else_tt: tt)*)) => { $($tt)+ }; (() else ($($else_tt: tt)*)) => { $($else_tt)* }; } pub(crate) use or; #[macro_export] macro_rules! expand_map_opt { ($in: tt, no_occurance=($($no_occurance: tt)*), occurance=($($occurance: tt)*)) => { $($occurance)* }; (, no_occurance=($($no_occurance: tt)*), occurance=($($occurance: tt)*)) => { $($no_occurance)* }; } #[macro_export] macro_rules! builder { ( $(#[doc = $doc: literal])* #[builder( name = $builder_name: ident $(, derives = ($($builder_derive: ident),+))? )] $(#[$attr: meta])* $visibility: vis struct $name: ident { $( $(#[doc = $field_doc: literal])* $(#[builder(skip_generate_fn$($field_skip_generate_fn: tt)?)])? $field_visibility: vis $field: ident: $field_type: ty, )* } ) => { $(#[doc = $doc])* $(#[$attr])* $visibility struct $name { $( $(#[doc = $field_doc])* $field_visibility $field: $field_type, )* } $(#[derive($($builder_derive),+)])? $visibility struct $builder_name { $( $field: $field_type, )* } impl $builder_name { $( $crate::expand_map_opt!( $(true $($field_skip_generate_fn)?)?, no_occurance=( #[must_use] $visibility fn $field(mut self, $field: $field_type) -> Self { self.$field = $field; self } ), occurance=() ); )* #[must_use] $visibility fn build(self) -> $name { $name { $( $field: self.$field, )* } } } impl From<$name> for $builder_name { #[allow(unused_variables)] fn from(built: $name) -> Self { Self { $( $field: built.$field, )* } } } }; }