Skip to content

Instantly share code, notes, and snippets.

@benfalk
Last active February 24, 2022 01:17
Show Gist options
  • Save benfalk/23eed2912716f5bc397d075ff7cd67cb to your computer and use it in GitHub Desktop.
Save benfalk/23eed2912716f5bc397d075ff7cd67cb to your computer and use it in GitHub Desktop.
use std::hash::Hash;
use std::cmp::Eq;
use std::any::{Any, TypeId};
use std::collections::HashMap;
pub struct AnyMap<K>(HashMap<(TypeId, K), Box<dyn Any>>);
impl<K: Hash + Eq> AnyMap<K> {
pub fn new() -> Self {
Self(HashMap::new())
}
pub fn insert<V: Any>(&mut self, key: K, val: V) {
self.0.insert((TypeId::of::<V>(), key), Box::new(val));
}
pub fn get<T: Any>(&self, key: K) -> Option<&T> {
self.0.get(&(TypeId::of::<T>(), key))?.downcast_ref::<T>()
}
pub fn get_mut<T: Any>(&mut self, key: K) -> Option<&mut T> {
self.0.get_mut(&(TypeId::of::<T>(), key))?.downcast_mut::<T>()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn can_store_anything() {
let pi: f64 = 3.142;
let hello: String = "Hello World".to_owned();
let mut storage = AnyMap::new();
storage.insert("pi", pi);
storage.insert("hello", hello);
assert_eq!(
storage.get::<f64>("pi").unwrap(),
&3.142
);
assert_eq!(
storage.get::<String>("hello").unwrap(),
&"Hello World".to_owned()
);
storage.get_mut::<String>("hello").unwrap().push_str("!!!");
assert_eq!(
storage.get::<String>("hello").unwrap(),
&"Hello World!!!".to_owned()
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment