nativeshell_core/util/
cell.rs

1use std::cell::UnsafeCell;
2
3/// Cell implementation that supports late initialization and can only be set once;
4/// Panics if data is accessed before set has been called or if set is called more than once.
5pub struct Late<T> {
6    value: UnsafeCell<Option<T>>,
7}
8
9impl<T> Late<T> {
10    /// Creates a new empty Late cell. You must call `set()` in order be able to
11    /// dereference the cell and access teh value.
12    pub fn new() -> Self {
13        Self {
14            value: UnsafeCell::new(None),
15        }
16    }
17
18    /// Returns whether this Late cell has value already set.
19    pub fn is_set(&self) -> bool {
20        let value = unsafe { &mut *self.value.get() };
21        value.is_some()
22    }
23
24    /// Sets the value of this cell. Panics if called more than once.
25    pub fn set(&self, new_value: T) {
26        let value = unsafe { &mut *self.value.get() };
27        match value {
28            Some(_) => {
29                panic!("Value is already set");
30            }
31            None => *value = Some(new_value),
32        }
33    }
34}
35
36impl<T> std::ops::Deref for Late<T> {
37    type Target = T;
38
39    fn deref(&self) -> &T {
40        let value = unsafe { &*self.value.get() };
41        match value {
42            Some(value) => value,
43            None => panic!("Late Value has not been set"),
44        }
45    }
46}