requiem_http/
extensions.rs1use std::any::{Any, TypeId};
2use std::fmt;
3
4use fxhash::FxHashMap;
5
6#[derive(Default)]
7pub struct Extensions {
9 map: FxHashMap<TypeId, Box<dyn Any>>,
10}
11
12impl Extensions {
13 #[inline]
15 pub fn new() -> Extensions {
16 Extensions {
17 map: FxHashMap::default(),
18 }
19 }
20
21 pub fn insert<T: 'static>(&mut self, val: T) {
26 self.map.insert(TypeId::of::<T>(), Box::new(val));
27 }
28
29 pub fn contains<T: 'static>(&self) -> bool {
31 self.map.get(&TypeId::of::<T>()).is_some()
32 }
33
34 pub fn get<T: 'static>(&self) -> Option<&T> {
36 self.map
37 .get(&TypeId::of::<T>())
38 .and_then(|boxed| (&**boxed as &(dyn Any + 'static)).downcast_ref())
39 }
40
41 pub fn get_mut<T: 'static>(&mut self) -> Option<&mut T> {
43 self.map
44 .get_mut(&TypeId::of::<T>())
45 .and_then(|boxed| (&mut **boxed as &mut (dyn Any + 'static)).downcast_mut())
46 }
47
48 pub fn remove<T: 'static>(&mut self) -> Option<T> {
52 self.map.remove(&TypeId::of::<T>()).and_then(|boxed| {
53 (boxed as Box<dyn Any + 'static>)
54 .downcast()
55 .ok()
56 .map(|boxed| *boxed)
57 })
58 }
59
60 #[inline]
62 pub fn clear(&mut self) {
63 self.map.clear();
64 }
65}
66
67impl fmt::Debug for Extensions {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 f.debug_struct("Extensions").finish()
70 }
71}
72
73#[test]
74fn test_extensions() {
75 #[derive(Debug, PartialEq)]
76 struct MyType(i32);
77
78 let mut extensions = Extensions::new();
79
80 extensions.insert(5i32);
81 extensions.insert(MyType(10));
82
83 assert_eq!(extensions.get(), Some(&5i32));
84 assert_eq!(extensions.get_mut(), Some(&mut 5i32));
85
86 assert_eq!(extensions.remove::<i32>(), Some(5i32));
87 assert!(extensions.get::<i32>().is_none());
88
89 assert_eq!(extensions.get::<bool>(), None);
90 assert_eq!(extensions.get(), Some(&MyType(10)));
91}