1use crate::rt::synchronize::Synchronize;
2use std::{any::Any, collections::HashMap};
3
4pub(crate) struct Set {
5 statics: Option<HashMap<StaticKeyId, StaticValue>>,
7}
8
9#[derive(Eq, PartialEq, Hash, Copy, Clone)]
10pub(crate) struct StaticKeyId(usize);
11
12pub(crate) struct StaticValue {
13 pub(crate) sync: Synchronize,
14 v: Box<dyn Any>,
15}
16
17impl Set {
18 pub(crate) fn new() -> Set {
20 Set {
21 statics: Some(HashMap::new()),
22 }
23 }
24
25 pub(crate) fn reset(&mut self) {
26 assert!(
27 self.statics.is_none(),
28 "lazy_static was not dropped during execution"
29 );
30 self.statics = Some(HashMap::new());
31 }
32
33 pub(crate) fn drop(&mut self) -> HashMap<StaticKeyId, StaticValue> {
34 self.statics
35 .take()
36 .expect("lazy_statics were dropped twice in one execution")
37 }
38
39 pub(crate) fn get_static<T: 'static>(
40 &mut self,
41 key: &'static crate::lazy_static::Lazy<T>,
42 ) -> Option<&mut StaticValue> {
43 self.statics
44 .as_mut()
45 .expect("attempted to access lazy_static during shutdown")
46 .get_mut(&StaticKeyId::new(key))
47 }
48
49 pub(crate) fn init_static<T: 'static>(
50 &mut self,
51 key: &'static crate::lazy_static::Lazy<T>,
52 value: StaticValue,
53 ) -> &mut StaticValue {
54 let v = self
55 .statics
56 .as_mut()
57 .expect("attempted to access lazy_static during shutdown")
58 .entry(StaticKeyId::new(key));
59
60 if let std::collections::hash_map::Entry::Occupied(_) = v {
61 unreachable!("told to init static, but it was already init'd");
62 }
63
64 v.or_insert(value)
65 }
66}
67
68impl StaticKeyId {
69 fn new<T>(key: &'static crate::lazy_static::Lazy<T>) -> Self {
70 Self(key as *const _ as usize)
71 }
72}
73
74impl StaticValue {
75 pub(crate) fn new<T: 'static>(value: T) -> Self {
76 Self {
77 sync: Synchronize::new(),
78 v: Box::new(value),
79 }
80 }
81
82 pub(crate) fn get<T: 'static>(&self) -> &T {
83 self.v
84 .downcast_ref::<T>()
85 .expect("lazy value must downcast to expected type")
86 }
87}