/// Macro to create a new trait bound typemap #[doc(hidden)] #[macro_export] macro_rules! impl_typemap { ($( #[$outer:meta] )* $map:ident, $key:ident, $($trt:ident), +) => { $( #[$outer] )* #[derive(Debug)] pub struct $map($crate::type_indexed::TypeIndexedMap); $crate::impl_typekey!($key $(, $trt )+); impl $crate::MapKey for $key { type Map = $map; } impl $crate::TypeMap for $map { type Key = $key; #[inline] fn new() -> Self { Self($crate::type_indexed::TypeIndexedMap::new()) } #[inline] fn insert>( &mut self, value: T::Value, ) { let mto = >::into_mto(value); self.0.insert::(mto); } #[inline] fn get>(&self) -> Option<&T::Value> { self.0.get::().and_then(|v| v.downcast_ref()) } #[inline] fn get_mut>( &mut self, ) -> Option<&mut T::Value> { self.0.get_mut::().and_then(|v| v.downcast_mut()) } #[inline] fn remove>( &mut self, ) -> Option { self.0.remove::().and_then(|v| v.downcast()) } #[inline] fn contains_key>(&self) -> bool { self.0.contains_key::() } } impl IntoIterator for $map { type Item = $crate::TypeMapEntry<$key>; type IntoIter = std::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.0 .0 .into_iter() .map(|(k, v)| $crate::TypeMapEntry::new(k, v)) .collect::>() .into_iter() } } impl $crate::MapCanExtend<$map> for T {} impl> FromIterator<$crate::TypeMapEntry> for $map { fn from_iter>>(iter: T2) -> Self { let map = iter .into_iter() .map(|e: $crate::TypeMapEntry| (e.type_id, e.mto)) .collect::>(); $map($crate::type_indexed::TypeIndexedMap(map)) } } impl> Extend<$crate::TypeMapEntry> for $map { fn extend>>(&mut self, iter: T) { let iter = iter .into_iter() .map(|e: $crate::TypeMapEntry| (e.type_id, e.mto)) .collect::>(); self.0.extend(iter) } } }; } #[doc(hidden)] #[macro_export] macro_rules! impl_typekey { ($key:ident, $($trt:ident), +) => { #[doc(hidden)] pub struct $key; impl $crate::TypedKeyTrait<$key> for T where T: $crate::TypeMapKey, ::Value: $crate::TypedKeyMto<$key> $(+ $trt )+, { type Value = T::Value; } impl $crate::TypedKeyMto<$key> for T { fn into_mto(self) -> multi_trait_object::MultitraitObject { multi_trait_object::create_object!(self $(, dyn $trt )+) } } } }