Created
July 10, 2017 17:21
-
-
Save scrogson/f3f018b55008df8e662874c11ddb6610 to your computer and use it in GitHub Desktop.
Assigns like Plug's conn.assigns - but type safe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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