You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
65 lines
1.4 KiB
65 lines
1.4 KiB
use std::any::{Any, TypeId};
|
|
use std::collections::HashMap;
|
|
|
|
#[derive(Default)]
|
|
pub struct Context {
|
|
container: HashMap<TypeId, Box<dyn Any>>,
|
|
}
|
|
|
|
impl Context {
|
|
pub fn get<T: 'static>(&self) -> Option<&T> {
|
|
self.container
|
|
.get(&TypeId::of::<T>())
|
|
.map(|boxed| boxed.downcast_ref().unwrap())
|
|
}
|
|
|
|
pub fn get_mut<T: 'static>(&mut self) -> Option<&mut T> {
|
|
self.container
|
|
.get_mut(&TypeId::of::<T>())
|
|
.map(|boxed| boxed.downcast_mut().unwrap())
|
|
}
|
|
|
|
pub fn set<T: 'static>(&mut self, t: T) {
|
|
self.container.insert(TypeId::of::<T>(), Box::from(t));
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_set_and_get() {
|
|
// Given Context
|
|
let mut context = Context::default();
|
|
// And values
|
|
context.set(1_u32);
|
|
context.set(String::from("text"));
|
|
|
|
// When
|
|
let num: &u32 = context.get().unwrap();
|
|
let text: &String = context.get().unwrap();
|
|
|
|
// Then
|
|
assert_eq!(*num, 1);
|
|
assert_eq!(text, "text");
|
|
}
|
|
|
|
#[test]
|
|
fn test_set_and_get_mut() {
|
|
// Given Context
|
|
let mut context = Context::default();
|
|
// And values
|
|
context.set(1_u32);
|
|
|
|
// When
|
|
{
|
|
let num: &mut u32 = context.get_mut().unwrap();
|
|
*num = 2;
|
|
}
|
|
let num: &u32 = context.get().unwrap();
|
|
|
|
// Then
|
|
assert_eq!(*num, 2);
|
|
}
|
|
}
|
|
|