Add FromIterator and IntoIterator implementations

Signed-off-by: trivernis <trivernis@protonmail.com>
main
trivernis 2 years ago
parent 51dd8a5c09
commit 86ca6ce3e1
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,6 +1,6 @@
[package] [package]
name = "trait-bound-typemap" name = "trait-bound-typemap"
version = "0.1.0" version = "0.2.0"
edition = "2021" edition = "2021"
license = "Apache-2.0" license = "Apache-2.0"
readme = "README.md" readme = "README.md"

@ -15,7 +15,7 @@ fat pointer used by trait objects changes which it hasn't in a long time so far.
## Usage ## Usage
```rust ```rust
use trait_bound_typemap::{CloneTypeMap, TypeMapTrait, TypeMapKey}; use trait_bound_typemap::{CloneTypeMap, AnyTypeMap, TypeMapTrait, TypeMapKey};
#[derive(Clone)] #[derive(Clone)]
pub struct MyStruct { pub struct MyStruct {
@ -34,6 +34,14 @@ fn main() {
let value = MyStruct {a: 5, b: String::from("Hello World")}; let value = MyStruct {a: 5, b: String::from("Hello World")};
map.insert::<MyStructKey>(value); map.insert::<MyStructKey>(value);
assert!(map.contains_key::<MyStructKey>()); assert!(map.contains_key::<MyStructKey>());
// can be cloned
let map2 = map.clone();
assert!(map.contains_key::<MyStructKey>());
// less restrictive is always allowed
let any_map = AnyTypeMap::from_iter(map2);
assert!(map.contains_key::<MyStructKey>());
} }
``` ```

@ -0,0 +1,19 @@
use multi_trait_object::MultitraitObject;
use std::any::TypeId;
use std::marker::PhantomData;
pub struct TypeMapEntry<T> {
pub type_id: TypeId,
pub mto: MultitraitObject,
_marker: PhantomData<T>,
}
impl<T> TypeMapEntry<T> {
pub fn new(type_id: TypeId, mto: MultitraitObject) -> Self {
Self {
type_id,
mto,
_marker: PhantomData,
}
}
}

@ -1,5 +1,6 @@
#![doc=include_str!("../README.md")] #![doc=include_str!("../README.md")]
mod entry;
mod macros; mod macros;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
@ -7,5 +8,6 @@ mod trait_maps;
mod type_indexed; mod type_indexed;
mod typemap_trait; mod typemap_trait;
pub use entry::*;
pub use trait_maps::*; pub use trait_maps::*;
pub use typemap_trait::*; pub use typemap_trait::*;

@ -7,8 +7,13 @@ macro_rules! impl_typemap {
$( #[$outer] )* $( #[$outer] )*
#[derive(Debug)] #[derive(Debug)]
pub struct $map($crate::type_indexed::TypeIndexedMap<multi_trait_object::MultitraitObject>); pub struct $map($crate::type_indexed::TypeIndexedMap<multi_trait_object::MultitraitObject>);
$crate::impl_typekey!($key, $( $trt )+); $crate::impl_typekey!($key, $( $trt )+);
impl $crate::MapKey for $key {
type Map = $map;
}
impl $crate::TypeMapTrait for $map { impl $crate::TypeMapTrait for $map {
type Key = $key; type Key = $key;
@ -50,6 +55,31 @@ macro_rules! impl_typemap {
self.0.contains_key::<T>() 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::MapKey<Map = M>, M: 'static $(+ $trt )+> 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))
}
}
}; };
} }

@ -1,4 +1,4 @@
use crate::{CloneTypeMap, PartialEqTypeMap, TypeMap, TypeMapKey, TypeMapTrait}; use crate::{AnyTypeMap, CloneTypeMap, PartialEqTypeMap, TypeMapKey, TypeMapTrait};
pub struct TestStructKey; pub struct TestStructKey;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -51,7 +51,7 @@ impl TypeMapKey for NotInsertedKey {
#[test] #[test]
fn it_creates_any_maps() { fn it_creates_any_maps() {
let mut map = TypeMap::new(); let mut map = AnyTypeMap::new();
map.insert::<NoCloneStruct>(NoCloneStruct); map.insert::<NoCloneStruct>(NoCloneStruct);
map.insert::<TestStructKey>(TestStruct::default()); map.insert::<TestStructKey>(TestStruct::default());
map.insert::<TestStruct2Key>(TestStruct2::default()); map.insert::<TestStruct2Key>(TestStruct2::default());
@ -79,3 +79,12 @@ fn it_creates_partial_eq_maps() {
map2.insert::<TestStructKey>(TestStruct::default()); map2.insert::<TestStructKey>(TestStruct::default());
assert_eq!(map, map2) assert_eq!(map, map2)
} }
#[test]
fn it_converts() {
let mut clone_map = CloneTypeMap::new();
clone_map.insert::<TestStructKey>(TestStruct::default());
assert!(clone_map.contains_key::<TestStructKey>());
let any_map = AnyTypeMap::from_iter(clone_map);
assert!(any_map.contains_key::<TestStructKey>());
}

@ -3,7 +3,7 @@ use std::any::Any;
impl_typemap!( impl_typemap!(
/// A typemap that can store any type (implementing [std::any::Any]). /// A typemap that can store any type (implementing [std::any::Any]).
TypeMap, AnyTypeMap,
AnyTypeMapKey, AnyTypeMapKey,
Any Any
); );

@ -21,6 +21,16 @@ pub trait TypedKeyMto<T> {
fn into_mto(self) -> MultitraitObject; fn into_mto(self) -> MultitraitObject;
} }
/// A trait to map the key to the map it describes
#[doc(hidden)]
pub trait MapKey {
type Map: TypeMapTrait<Key = Self>;
}
/// A marker trait to transfer trait information
#[doc(hidden)]
pub trait TraitCarrier<T> {}
/// A trait implemented by all typemaps that provides /// A trait implemented by all typemaps that provides
/// all basic typemap functions /// all basic typemap functions
pub trait TypeMapTrait { pub trait TypeMapTrait {

Loading…
Cancel
Save