lucet_runtime_internals/
embed_ctx.rs

1use std::any::{Any, TypeId};
2use std::cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut};
3use std::collections::HashMap;
4
5/// A map that holds at most one value of any type.
6///
7/// This is similar to the type provided by the `anymap` crate, but we can get away with simpler
8/// types on the methods due to our more specialized use case.
9#[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}