lucet_runtime_internals/
embed_ctx.rs1use std::any::{Any, TypeId};
2use std::cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut};
3use std::collections::HashMap;
4
5#[derive(Default)]
10pub struct CtxMap {
11 map: HashMap<TypeId, RefCell<Box<dyn Any>>>,
12}
13
14impl CtxMap {
15 pub fn clear(&mut self) {
16 self.map.clear();
17 }
18
19 pub fn contains<T: Any>(&self) -> bool {
20 self.map.contains_key(&TypeId::of::<T>())
21 }
22
23 pub fn try_get<T: Any>(&self) -> Option<Result<Ref<'_, T>, BorrowError>> {
24 self.map.get(&TypeId::of::<T>()).map(|x| {
25 x.try_borrow().map(|r| {
26 Ref::map(r, |b| {
27 b.downcast_ref::<T>()
28 .expect("value stored with TypeId::of::<T> is always type T")
29 })
30 })
31 })
32 }
33
34 pub fn try_get_mut<T: Any>(&self) -> Option<Result<RefMut<'_, T>, BorrowMutError>> {
35 self.map.get(&TypeId::of::<T>()).map(|x| {
36 x.try_borrow_mut().map(|r| {
37 RefMut::map(r, |b| {
38 b.downcast_mut::<T>()
39 .expect("value stored with TypeId::of::<T> is always type T")
40 })
41 })
42 })
43 }
44
45 pub fn insert<T: Any>(&mut self, x: T) -> Option<T> {
46 self.map
47 .insert(TypeId::of::<T>(), RefCell::new(Box::new(x) as Box<dyn Any>))
48 .map(|x_prev| {
49 *(x_prev.into_inner())
50 .downcast::<T>()
51 .expect("value stored with TypeId::of::<T> is always type T")
52 })
53 }
54
55 pub fn remove<T: Any>(&mut self) -> Option<T> {
56 self.map.remove(&TypeId::of::<T>()).map(|x| {
57 *(x.into_inner())
58 .downcast::<T>()
59 .expect("value stored with TypeId::of::<T> is always type T")
60 })
61 }
62
63 pub fn new() -> Self {
64 Self::default()
65 }
66}