Skip to content

Instantly share code, notes, and snippets.

@scrogson
Created July 10, 2017 17:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scrogson/f3f018b55008df8e662874c11ddb6610 to your computer and use it in GitHub Desktop.
Save scrogson/f3f018b55008df8e662874c11ddb6610 to your computer and use it in GitHub Desktop.
Assigns like Plug's conn.assigns - but type safe
use ::std::collections::HashMap;
use ::std::any::{TypeId, Any};
struct Assigns {
map: HashMap<TypeId, Box<Any>>,
}
trait AssignHandle {
type MapsTo;
}
impl Assigns {
fn new() -> Self {
Assigns {
map: HashMap::new(),
}
}
fn set<T>(&mut self, handle: T, value: T::MapsTo)
where T: AssignHandle + 'static
{
self.map.insert(TypeId::of::<T>(), Box::new(value));
}
fn get<'a, T>(&'a self, handle: T) -> Option<&'a T::MapsTo>
where T: AssignHandle + 'static
{
self.map.get(&TypeId::of::<T>()).map(|t| t.downcast_ref().unwrap())
}
}
// Could have a macro for this
struct SomeAssign;
impl AssignHandle for SomeAssign {
type MapsTo = u32;
}
struct SomeOtherAssign;
impl AssignHandle for SomeOtherAssign {
type MapsTo = String;
}
fn main() {
let mut assigns = Assigns::new();
assigns.set(SomeAssign, 12);
assigns.set(SomeOtherAssign, "blah".to_string());
println!("{:?}", assigns.get(SomeAssign));
println!("{:?}", assigns.get(SomeOtherAssign));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment