You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
3.9 KiB
Rust

/// 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<multi_trait_object::MultitraitObject>);
$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<T: $crate::TypedKeyTrait<Self::Key>>(
&mut self,
value: T::Value,
) {
let mto = <T::Value as $crate::TypedKeyMto<Self::Key>>::into_mto(value);
self.0.insert::<T>(mto);
}
#[inline]
fn get<T: $crate::TypedKeyTrait<Self::Key>>(&self) -> Option<&T::Value> {
self.0.get::<T>().and_then(|v| v.downcast_ref())
}
#[inline]
fn get_mut<T: $crate::TypedKeyTrait<Self::Key>>(
&mut self,
) -> Option<&mut T::Value> {
self.0.get_mut::<T>().and_then(|v| v.downcast_mut())
}
#[inline]
fn remove<T: $crate::TypedKeyTrait<Self::Key>>(
&mut self,
) -> Option<T::Value> {
self.0.remove::<T>().and_then(|v| v.downcast())
}
#[inline]
fn contains_key<T: $crate::TypedKeyTrait<Self::Key>>(&self) -> bool {
self.0.contains_key::<T>()
}
}
impl IntoIterator for $map {
type Item = $crate::TypeMapEntry<$key>;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.0
.0
.into_iter()
.map(|(k, v)| $crate::TypeMapEntry::new(k, v))
.collect::<Vec<Self::Item>>()
.into_iter()
}
}
impl<T: $crate::TypeMap $(+ $trt )+> $crate::MapCanExtend<$map> for T {}
impl<T: $crate::KeyCanExtend<$map>> FromIterator<$crate::TypeMapEntry<T>> for $map {
fn from_iter<T2: IntoIterator<Item = $crate::TypeMapEntry<T>>>(iter: T2) -> Self {
let map = iter
.into_iter()
.map(|e: $crate::TypeMapEntry<T>| (e.type_id, e.mto))
.collect::<std::collections::HashMap<std::any::TypeId, multi_trait_object::MultitraitObject>>();
$map($crate::type_indexed::TypeIndexedMap(map))
}
}
impl<K: $crate::KeyCanExtend<$map>> Extend<$crate::TypeMapEntry<K>> for $map {
fn extend<T: IntoIterator<Item = $crate::TypeMapEntry<K>>>(&mut self, iter: T) {
let iter = iter
.into_iter()
.map(|e: $crate::TypeMapEntry<K>| (e.type_id, e.mto))
.collect::<Vec<(std::any::TypeId, multi_trait_object::MultitraitObject)>>();
self.0.extend(iter)
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! impl_typekey {
($key:ident, $($trt:ident), +) => {
#[doc(hidden)]
pub struct $key;
impl<T> $crate::TypedKeyTrait<$key> for T
where
T: $crate::TypeMapKey,
<T as $crate::TypeMapKey>::Value: $crate::TypedKeyMto<$key> $(+ $trt )+,
{
type Value = T::Value;
}
impl<T: 'static $(+ $trt )+> $crate::TypedKeyMto<$key> for T {
fn into_mto(self) -> multi_trait_object::MultitraitObject {
multi_trait_object::create_object!(self $(, dyn $trt )+)
}
}
}
}