1 | use crate::util::AnyValue; |
2 | use crate::util::AnyValueId; |
3 | use crate::util::FlatMap; |
4 | |
5 | #[derive (Default, Clone, Debug)] |
6 | pub(crate) struct Extensions { |
7 | extensions: FlatMap<AnyValueId, AnyValue>, |
8 | } |
9 | |
10 | impl Extensions { |
11 | #[allow (dead_code)] |
12 | pub(crate) fn get<T: Extension>(&self) -> Option<&T> { |
13 | let id = AnyValueId::of::<T>(); |
14 | self.extensions.get(&id).map(|e| { |
15 | e.downcast_ref::<T>() |
16 | .expect("`Extensions` tracks values by type" ) |
17 | }) |
18 | } |
19 | |
20 | #[allow (dead_code)] |
21 | pub(crate) fn set<T: Extension>(&mut self, tagged: T) -> bool { |
22 | let value = AnyValue::new(tagged); |
23 | let id = value.type_id(); |
24 | self.extensions.insert(id, value).is_some() |
25 | } |
26 | |
27 | #[allow (dead_code)] |
28 | pub(crate) fn remove<T: Extension>(&mut self) -> Option<T> { |
29 | let id = AnyValueId::of::<T>(); |
30 | self.extensions.remove(&id).map(|e| { |
31 | e.downcast_into::<T>() |
32 | .expect("`Extensions` tracks values by type" ) |
33 | }) |
34 | } |
35 | |
36 | pub(crate) fn update(&mut self, other: &Self) { |
37 | for (key, value) in other.extensions.iter() { |
38 | self.extensions.insert(*key, value.clone()); |
39 | } |
40 | } |
41 | } |
42 | |
43 | #[allow (unreachable_pub)] |
44 | pub trait Extension: std::fmt::Debug + Clone + std::any::Any + Send + Sync + 'static {} |
45 | |
46 | impl<T> Extension for T where T: std::fmt::Debug + Clone + std::any::Any + Send + Sync + 'static {} |
47 | |