easy_di/
service_provider_extensions.rs

1use std::any::{Any, TypeId};
2
3use ahash::AHashMap;
4
5/// A type map for dependency injections.
6///
7/// All entries into this map must be owned types (or static references).
8#[derive(Default)]
9pub struct ServiceProviderExtensions {
10    /// Use AHasher with a std HashMap with for faster lookups on the small `TypeId` keys.
11    map: AHashMap<TypeId, Box<dyn Any + Sync + Send>>,
12}
13
14impl ServiceProviderExtensions {
15    pub fn insert<T: 'static + Sync + Send>(&mut self, val: T) -> Option<T> {
16        self.insert_type_id(TypeId::of::<T>(), val)
17    }
18
19    fn insert_type_id<T: 'static + Sync + Send>(&mut self, type_id: TypeId, val: T) -> Option<T> {
20        self.map
21            .insert(type_id, Box::new(val))
22            .and_then(downcast_owned)
23    }
24
25    pub fn get<T: 'static>(&self) -> Option<&T> {
26        let elem = self.map.get(&TypeId::of::<T>());
27        elem.and_then(|boxed| boxed.downcast_ref::<T>())
28    }
29
30    pub fn len(&self) -> usize {
31        self.map.len()
32    }
33
34    pub fn is_empty(&self) -> bool {
35        self.map.is_empty()
36    }
37}
38
39fn downcast_owned<T: 'static + Sync>(boxed: Box<dyn Any + Sync + Send>) -> Option<T> {
40    boxed.downcast().ok().map(|boxed| *boxed)
41}