1use std::any::{Any, TypeId};
7use std::sync::Arc;
8use std::collections::HashMap;
9use std::hash::{BuildHasherDefault, Hasher};
10use std::fmt;
11
12type AnyMap = HashMap<TypeId, Box<Any + Send + Sync>, BuildHasherDefault<IdHasher>>;
13
14#[derive(Debug, Default)]
15struct IdHasher(u64);
16
17impl Hasher for IdHasher {
18 fn write(&mut self, _: &[u8]) {
19 unreachable!("TypeId calls write_u64");
20 }
21
22 #[inline]
23 fn write_u64(&mut self, id: u64) {
24 self.0 = id;
25 }
26
27 #[inline]
28 fn finish(&self) -> u64 {
29 self.0
30 }
31}
32
33pub(crate) struct ConfigBuilder {
34 inner: AnyMap,
35}
36
37impl ConfigBuilder {
38 pub(crate) fn new() -> Self {
39 Self { inner: AnyMap::default() }
40 }
41
42 pub(crate) fn insert<T: Send + Sync + 'static>(mut self, val: T) -> Self {
43 self.inner.insert(TypeId::of::<T>(), Box::new(val));
44 self
45 }
46
47 pub(crate) fn into_config(self) -> Config {
48 Config { inner: Arc::new(self.inner) }
49 }
50}
51
52impl fmt::Debug for ConfigBuilder {
53 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54 f.debug_struct("ConfigBuilder")
55 .finish()
56 }
57}
58
59#[derive(Clone)]
61pub struct Config {
62 inner: Arc<AnyMap>,
63}
64
65impl Config {
66 pub fn get<T: 'static>(&self) -> Option<&T> {
71 self.inner
72 .get(&TypeId::of::<T>())
73 .and_then(|boxed| {
74 (&**boxed as &Any).downcast_ref()
75 })
76 }
77}
78
79impl fmt::Debug for Config {
80 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81 f.debug_struct("Config")
82 .finish()
83 }
84}