shuttle_engine/runtime/
storage.rs1use std::any::Any;
2use std::collections::{HashMap, VecDeque};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6pub struct StorageKey(pub usize, pub usize); #[derive(Debug)]
15pub struct StorageMap {
16 locals: HashMap<StorageKey, Option<Box<dyn Any>>>,
17 order: VecDeque<StorageKey>,
18}
19
20impl StorageMap {
21 pub fn new() -> Self {
22 Self {
23 locals: HashMap::new(),
24 order: VecDeque::new(),
25 }
26 }
27
28 pub fn get<T: 'static>(&self, key: StorageKey) -> Option<Result<&T, AlreadyDestructedError>> {
29 self.locals.get(&key).map(|val| {
30 val.as_ref()
31 .map(|val| {
32 Ok(val
33 .downcast_ref::<T>()
34 .expect("local value must downcast to expected type"))
35 })
36 .unwrap_or(Err(AlreadyDestructedError))
37 })
38 }
39
40 pub fn init<T: 'static>(&mut self, key: StorageKey, value: T) {
41 let result = self.locals.insert(key, Some(Box::new(value)));
42 assert!(result.is_none(), "cannot reinitialize a storage slot");
43 self.order.push_back(key);
44 }
45
46 pub fn is_empty(&self) -> bool {
48 self.order.is_empty()
49 }
50
51 pub fn pop(&mut self) -> Option<Box<dyn Any>> {
53 let key = self.order.pop_front()?;
54 let value = self
55 .locals
56 .get_mut(&key)
57 .expect("keys in `order` must exist")
58 .take()
59 .expect("keys in `order` must not yet be destructed");
60 Some(value)
61 }
62}
63
64#[derive(Debug)]
65#[non_exhaustive]
66pub struct AlreadyDestructedError;