1#![deny(missing_docs, warnings)]
2
3extern crate unsafe_any as uany;
6
7use uany::{UnsafeAny, UnsafeAnyExt};
8use std::any::{Any, TypeId};
9use std::collections::{hash_map, HashMap};
10use std::marker::PhantomData;
11
12use Entry::{Occupied, Vacant};
13
14pub use internals::{CloneAny, DebugAny};
15use internals::Implements;
16
17#[derive(Default, Debug)]
27pub struct TypeMap<A: ?Sized = UnsafeAny>
28where A: UnsafeAnyExt {
29 data: HashMap<TypeId, Box<A>>
30}
31
32impl<A: ?Sized> Clone for TypeMap<A>
33where A: UnsafeAnyExt, Box<A>: Clone { fn clone(&self) -> TypeMap<A> {
35 TypeMap { data: self.data.clone() }
36 }
37}
38
39pub type SendMap = TypeMap<UnsafeAny + Send>;
41
42pub type SyncMap = TypeMap<UnsafeAny + Sync>;
44
45pub type ShareMap = TypeMap<UnsafeAny + Send + Sync>;
47
48pub type CloneMap = TypeMap<CloneAny>;
50
51pub type ShareCloneMap = TypeMap<CloneAny + Send + Sync>;
53
54pub type DebugMap = TypeMap<DebugAny>;
56
57pub type ShareDebugMap = TypeMap<DebugAny + Send + Sync>;
59
60fn _assert_types() {
62 use std::fmt::Debug;
63
64 fn _assert_send<T: Send>() { }
65 fn _assert_sync<T: Sync>() { }
66 fn _assert_clone<T: Clone>() { }
67 fn _assert_debug<T: Debug>() { }
68
69 _assert_send::<SendMap>();
70 _assert_sync::<SyncMap>();
71 _assert_send::<ShareMap>();
72 _assert_sync::<ShareMap>();
73 _assert_clone::<CloneMap>();
74 _assert_debug::<DebugMap>();
75}
76
77pub trait Key: Any {
81 type Value: Any;
83}
84
85impl TypeMap {
86 pub fn new() -> TypeMap {
88 TypeMap::custom()
89 }
90}
91
92impl<A: UnsafeAnyExt + ?Sized> TypeMap<A> {
93 pub fn custom() -> TypeMap<A> {
98 TypeMap {
99 data: HashMap::new()
100 }
101 }
102
103 pub fn insert<K: Key>(&mut self, val: K::Value) -> Option<K::Value>
105 where K::Value: Any + Implements<A> {
106 self.data.insert(TypeId::of::<K>(), val.into_object()).map(|v| unsafe {
107 *v.downcast_unchecked::<K::Value>()
108 })
109 }
110
111 pub fn get<K: Key>(&self) -> Option<&K::Value>
113 where K::Value: Any + Implements<A> {
114 self.data.get(&TypeId::of::<K>()).map(|v| unsafe {
115 v.downcast_ref_unchecked::<K::Value>()
116 })
117 }
118
119 pub fn get_mut<K: Key>(&mut self) -> Option<&mut K::Value>
121 where K::Value: Any + Implements<A> {
122 self.data.get_mut(&TypeId::of::<K>()).map(|v| unsafe {
123 v.downcast_mut_unchecked::<K::Value>()
124 })
125 }
126
127 pub fn contains<K: Key>(&self) -> bool {
129 self.data.contains_key(&TypeId::of::<K>())
130 }
131
132 pub fn remove<K: Key>(&mut self) -> Option<K::Value>
136 where K::Value: Any + Implements<A> {
137 self.data.remove(&TypeId::of::<K>()).map(|v| unsafe {
138 *v.downcast_unchecked::<K::Value>()
139 })
140 }
141
142 pub fn entry<'a, K: Key>(&'a mut self) -> Entry<'a, K, A>
144 where K::Value: Any + Implements<A> {
145 match self.data.entry(TypeId::of::<K>()) {
146 hash_map::Entry::Occupied(e) => Occupied(OccupiedEntry { data: e, _marker: PhantomData }),
147 hash_map::Entry::Vacant(e) => Vacant(VacantEntry { data: e, _marker: PhantomData })
148 }
149 }
150
151 pub unsafe fn data(&self) -> &HashMap<TypeId, Box<A>> {
153 &self.data
154 }
155
156 pub unsafe fn data_mut(&mut self) -> &mut HashMap<TypeId, Box<A>> {
158 &mut self.data
159 }
160
161 pub fn len(&self) -> usize {
163 self.data.len()
164 }
165
166 pub fn is_empty(&self) -> bool {
168 self.data.is_empty()
169 }
170
171 pub fn clear(&mut self) {
173 self.data.clear()
174 }
175}
176
177pub enum Entry<'a, K, A: ?Sized + UnsafeAnyExt + 'a = UnsafeAny> {
179 Occupied(OccupiedEntry<'a, K, A>),
181 Vacant(VacantEntry<'a, K, A>)
183}
184
185impl<'a, K: Key, A: ?Sized + UnsafeAnyExt + 'a = UnsafeAny> Entry<'a, K, A> {
186 pub fn or_insert(self, default: K::Value) -> &'a mut K::Value
189 where K::Value: Any + Implements<A> {
190 match self {
191 Entry::Occupied(inner) => inner.into_mut(),
192 Entry::Vacant(inner) => inner.insert(default),
193 }
194 }
195
196 pub fn or_insert_with<F: FnOnce() -> K::Value>(self, default: F) -> &'a mut K::Value
199 where K::Value: Any + Implements<A> {
200 match self {
201 Entry::Occupied(inner) => inner.into_mut(),
202 Entry::Vacant(inner) => inner.insert(default()),
203 }
204 }
205}
206
207pub struct OccupiedEntry<'a, K, A: ?Sized + UnsafeAnyExt + 'a = UnsafeAny> {
209 data: hash_map::OccupiedEntry<'a, TypeId, Box<A>>,
210 _marker: PhantomData<K>
211}
212
213pub struct VacantEntry<'a, K, A: ?Sized + UnsafeAnyExt + 'a = UnsafeAny> {
215 data: hash_map::VacantEntry<'a, TypeId, Box<A>>,
216 _marker: PhantomData<K>
217}
218
219impl<'a, K: Key, A: UnsafeAnyExt + ?Sized> OccupiedEntry<'a, K, A> {
220 pub fn get(&self) -> &K::Value
222 where K::Value: Any + Implements<A> {
223 unsafe {
224 self.data.get().downcast_ref_unchecked()
225 }
226 }
227
228 pub fn get_mut(&mut self) -> &mut K::Value
230 where K::Value: Any + Implements<A> {
231 unsafe {
232 self.data.get_mut().downcast_mut_unchecked()
233 }
234 }
235
236 pub fn into_mut(self) -> &'a mut K::Value
238 where K::Value: Any + Implements<A> {
239 unsafe {
240 self.data.into_mut().downcast_mut_unchecked()
241 }
242 }
243
244 pub fn insert(&mut self, value: K::Value) -> K::Value
246 where K::Value: Any + Implements<A> {
247 unsafe {
248 *self.data.insert(value.into_object()).downcast_unchecked()
249 }
250 }
251
252 pub fn remove(self) -> K::Value
254 where K::Value: Any + Implements<A> {
255 unsafe {
256 *self.data.remove().downcast_unchecked()
257 }
258 }
259}
260
261impl<'a, K: Key, A: ?Sized + UnsafeAnyExt> VacantEntry<'a, K, A> {
262 pub fn insert(self, value: K::Value) -> &'a mut K::Value
264 where K::Value: Any + Implements<A> {
265 unsafe {
266 self.data.insert(value.into_object()).downcast_mut_unchecked()
267 }
268 }
269}
270
271mod internals;
272
273#[cfg(test)]
274mod test {
275 use super::{TypeMap, CloneMap, DebugMap, SendMap, Key};
276 use super::Entry::{Occupied, Vacant};
277
278 #[derive(Debug, PartialEq)]
279 struct KeyType;
280
281 #[derive(Clone, Debug, PartialEq)]
282 struct Value(u8);
283
284 impl Key for KeyType { type Value = Value; }
285
286 #[test] fn test_pairing() {
287 let mut map = TypeMap::new();
288 map.insert::<KeyType>(Value(100));
289 assert_eq!(*map.get::<KeyType>().unwrap(), Value(100));
290 assert!(map.contains::<KeyType>());
291 }
292
293 #[test] fn test_remove() {
294 let mut map = TypeMap::new();
295 map.insert::<KeyType>(Value(10));
296 assert!(map.contains::<KeyType>());
297 map.remove::<KeyType>();
298 assert!(!map.contains::<KeyType>());
299 }
300
301 #[test] fn test_entry() {
302 let mut map = TypeMap::new();
303 map.insert::<KeyType>(Value(20));
304 match map.entry::<KeyType>() {
305 Occupied(e) => {
306 assert_eq!(e.get(), &Value(20));
307 assert_eq!(e.remove(), Value(20));
308 },
309 _ => panic!("Unable to locate inserted item.")
310 }
311 assert!(!map.contains::<KeyType>());
312 match map.entry::<KeyType>() {
313 Vacant(e) => {
314 e.insert(Value(2));
315 },
316 _ => panic!("Found non-existant entry.")
317 }
318 assert!(map.contains::<KeyType>());
319 }
320
321 #[test] fn test_entry_or_insert() {
322 let mut map = TypeMap::new();
323 map.entry::<KeyType>().or_insert(Value(20)).0 += 1;
324 assert_eq!(map.get::<KeyType>().unwrap(), &Value(21));
325
326 map.entry::<KeyType>().or_insert(Value(100)).0 += 1;
328 assert_eq!(map.get::<KeyType>().unwrap(), &Value(22));
329 }
330
331 #[test] fn test_custom_bounds() {
332 let mut map: SendMap = TypeMap::custom();
333 map.insert::<KeyType>(Value(10));
334 assert!(map.contains::<KeyType>());
335 map.remove::<KeyType>();
336 assert!(!map.contains::<KeyType>());
337 }
338
339 #[test] fn test_clonemap() {
340 let mut map: CloneMap = TypeMap::custom();
341 map.insert::<KeyType>(Value(10));
342 assert!(map.contains::<KeyType>());
343 let cloned = map.clone();
344 assert_eq!(map.get::<KeyType>(), cloned.get::<KeyType>());
345 }
346
347 #[test] fn test_debugmap() {
348 let mut map: DebugMap = TypeMap::custom();
349 map.insert::<KeyType>(Value(10));
350 assert!(map.contains::<KeyType>());
351 }
352}