badcontext 0.1.0

A small crate for creating Context structs that contain application components
Documentation
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);
    }
}