Skip to content

Instantly share code, notes, and snippets.

@reem
Created August 12, 2014 01:27
Show Gist options
  • Save reem/025c2af1fef2e661896f to your computer and use it in GitHub Desktop.
Save reem/025c2af1fef2e661896f to your computer and use it in GitHub Desktop.
use std::any::{Any, AnyRefExt, AnyMutRefExt};
use std::intrinsics::TypeId;
use std::collections::HashMap;
/// A map which can contain one value of any type and is keyed by types.
///
/// Values must implement the `Any` trait.
pub struct TypeMap {
map: HashMap<TypeId, Box<Any>>
}
impl TypeMap {
pub fn new() -> TypeMap {
TypeMap { map: HashMap::new() }
}
pub fn find<T: 'static>(&self) -> Option<&T> {
self.map.find(&TypeId::of::<T>()).and_then(|any| any.downcast_ref())
}
pub fn find_mut<T: 'static>(&mut self) -> Option<&mut T> {
self.map.find_mut(&TypeId::of::<T>()).and_then(|any| any.downcast_mut())
}
pub fn insert<T: 'static>(&mut self, t: T) {
self.map.insert(TypeId::of::<T>(), box t as Box<Any>);
}
pub fn remove<T: 'static>(&mut self) {
self.map.remove(&TypeId::of::<T>());
}
}
#[test] fn test_simple() {
let mut data = TypeMap::new();
assert_eq!(data.find(), None::<&uint>);
data.insert(74u);
assert_eq!(data.find(), Some(&74u));
data.remove::<uint>();
assert_eq!(data.find(), None::<&uint>);
}
#[test] fn test_complex() {
#[deriving(PartialEq, Show)]
struct Foo {
str: String,
}
let mut data = TypeMap::new();
assert_eq!(data.find::<Foo>(), None);
data.insert(Foo { str: "foo".to_string() });
assert_eq!(data.find(), Some(&Foo { str: "foo".to_string() }));
data.find_mut::<Foo>().map(|foo| foo.str.push_char('t'));
assert_eq!(data.find::<Foo>().unwrap().str.as_slice(), "foot");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment