diff --git a/src/base.rs b/src/base.rs index 953580f..bf7f08b 100644 --- a/src/base.rs +++ b/src/base.rs @@ -2,6 +2,10 @@ use multi_trait_object::MultitraitObject; use std::any::TypeId; use std::collections::HashMap; +/// Base typemap used for implementation but not elsewhere +/// Each other typemap is just a newtype of this base type with +/// additional implementation. +#[doc(hidden)] #[derive(Debug, Default)] pub(crate) struct TypeMapBase(pub(crate) HashMap); diff --git a/src/lib.rs b/src/lib.rs index a92c966..fc05940 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ #![doc=include_str!("../README.md")] mod base; -pub(crate) mod macros; +mod macros; #[cfg(test)] mod tests; mod trait_maps; diff --git a/src/macros.rs b/src/macros.rs index ae1a546..fbf1135 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,10 +1,14 @@ +/// Macro to create a new trait bound typemap #[doc(hidden)] #[macro_export] macro_rules! impl_typemap { - ($map:ident, $key:ty) => { + ($( #[$outer:meta] )* + $map:ident, $key:ident, $($trt:ident), +) => { + $( #[$outer] )* pub struct $map($crate::base::TypeMapBase); + $crate::impl_typekey!($key, $( $trt )+); - impl $crate::typemap_trait::TypeMapTrait for $map { + impl $crate::TypeMapTrait for $map { type Key = $key; #[inline] @@ -13,37 +17,60 @@ macro_rules! impl_typemap { } #[inline] - fn insert>( + fn insert>( &mut self, value: T::Value, ) { - let mto = value.into_mto(); + let mto = >::into_mto(value); self.0.insert::(mto); } #[inline] - fn get>(&self) -> Option<&T::Value> { + fn get>(&self) -> Option<&T::Value> { self.0.get::().and_then(|v| v.downcast_ref()) } #[inline] - fn get_mut>( + fn get_mut>( &mut self, ) -> Option<&mut T::Value> { self.0.get_mut::().and_then(|v| v.downcast_mut()) } #[inline] - fn remove>( + fn remove>( &mut self, ) -> Option { self.0.remove::().and_then(|v| v.downcast()) } #[inline] - fn contains_key>(&self) -> bool { + fn contains_key>(&self) -> bool { self.0.contains_key::() } } }; } + +#[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 )+) + } + } + } +} diff --git a/src/trait_maps/clone_typemap.rs b/src/trait_maps/clone_typemap.rs index 82b22a3..1aa0b45 100644 --- a/src/trait_maps/clone_typemap.rs +++ b/src/trait_maps/clone_typemap.rs @@ -1,24 +1,14 @@ use crate::base::TypeMapBase; -use crate::{impl_typemap, TypeMapKey, TypedKeyMto, TypedKeyTrait}; -use multi_trait_object::{create_object, MultitraitObject, RawClone, TryClone}; +use crate::impl_typemap; +use multi_trait_object::{RawClone, TryClone}; -pub struct CloneTypeMapKey; - -impl TypedKeyTrait for T -where - T: TypeMapKey, - ::Value: TypedKeyMto + Clone, -{ - type Value = T::Value; -} - -impl TypedKeyMto for T { - fn into_mto(self) -> MultitraitObject { - create_object!(self, dyn RawClone) - } -} - -impl_typemap!(CloneTypeMap, CloneTypeMapKey); +impl_typemap!( + /// A typemap that can be cloned restricting all inner + /// types to implement [std::clone::Clone] as well. + CloneTypeMap, + CloneTypeMapKey, + RawClone +); impl Clone for CloneTypeMap { fn clone(&self) -> Self { diff --git a/src/trait_maps/typemap.rs b/src/trait_maps/typemap.rs index 4ea5649..0044b4e 100644 --- a/src/trait_maps/typemap.rs +++ b/src/trait_maps/typemap.rs @@ -1,22 +1,9 @@ -use crate::{impl_typemap, TypeMapKey, TypedKeyMto, TypedKeyTrait}; -use multi_trait_object::{create_object, MultitraitObject}; +use crate::impl_typemap; use std::any::Any; -#[derive(Eq, PartialEq, Hash)] -pub struct AnyTypeMapKey; - -impl TypedKeyTrait for T -where - T: TypeMapKey, - ::Value: Any, -{ - type Value = T::Value; -} - -impl TypedKeyMto for T { - fn into_mto(self) -> MultitraitObject { - create_object!(self, dyn Any) - } -} - -impl_typemap!(TypeMap, AnyTypeMapKey); +impl_typemap!( + /// A typemap that can store any type (implementing [std::any::Any]). + TypeMap, + AnyTypeMapKey, + Any +); diff --git a/src/typemap_trait.rs b/src/typemap_trait.rs index 51236e8..56ebef5 100644 --- a/src/typemap_trait.rs +++ b/src/typemap_trait.rs @@ -9,12 +9,14 @@ pub trait TypeMapKey: 'static { /// A trait used for restricting values inserted in a type map /// using type checking +#[doc(hidden)] pub trait TypedKeyTrait: 'static { type Value: TypedKeyMto; } /// A trait used to create a multitrait-object from a given /// value with the given guaranteed trait implementations +#[doc(hidden)] pub trait TypedKeyMto { fn into_mto(self) -> MultitraitObject; }