commonware_runtime/utils/
cell.rs1use std::ops::{Deref, DerefMut};
2
3const MISSING_CONTEXT: &str = "runtime context missing";
4const DUPLICATE_CONTEXT: &str = "runtime context already present";
5
6#[macro_export]
13macro_rules! spawn_cell {
14 ($cell:expr, $body:expr $(,)?) => {{
15 let __commonware_context = $cell.take();
16 $crate::Spawner::spawn(__commonware_context, move |context| {
17 $cell.restore(context);
18 $body
19 })
20 }};
21}
22
23#[derive(Debug)]
26pub enum Cell<C> {
27 Present(C),
29 Missing,
31}
32
33impl<C> Cell<C> {
34 pub const fn new(context: C) -> Self {
36 Self::Present(context)
37 }
38
39 pub fn take(&mut self) -> C {
41 match std::mem::replace(self, Self::Missing) {
42 Self::Present(context) => context,
43 Self::Missing => panic!("{}", MISSING_CONTEXT),
44 }
45 }
46
47 pub fn restore(&mut self, context: C) {
49 match self {
50 Self::Present(_) => panic!("{}", DUPLICATE_CONTEXT),
51 Self::Missing => {
52 *self = Self::Present(context);
53 }
54 }
55 }
56
57 pub fn as_present(&self) -> &C {
63 match self {
64 Self::Present(context) => context,
65 Self::Missing => panic!("{}", MISSING_CONTEXT),
66 }
67 }
68
69 pub fn as_present_mut(&mut self) -> &mut C {
75 match self {
76 Self::Present(context) => context,
77 Self::Missing => panic!("{}", MISSING_CONTEXT),
78 }
79 }
80
81 pub fn into_present(self) -> C {
87 match self {
88 Self::Present(context) => context,
89 Self::Missing => panic!("{}", MISSING_CONTEXT),
90 }
91 }
92}
93
94impl<C> Deref for Cell<C> {
95 type Target = C;
96
97 fn deref(&self) -> &C {
98 self.as_present()
99 }
100}
101
102impl<C> DerefMut for Cell<C> {
103 fn deref_mut(&mut self) -> &mut C {
104 self.as_present_mut()
105 }
106}
107
108impl<C> AsRef<C> for Cell<C> {
109 fn as_ref(&self) -> &C {
110 self.as_present()
111 }
112}
113
114impl<C> AsMut<C> for Cell<C> {
115 fn as_mut(&mut self) -> &mut C {
116 self.as_present_mut()
117 }
118}