leetcode_tui_shared/
ro_cell.rs

1use std::{
2    cell::UnsafeCell,
3    fmt::{self, Display},
4};
5
6// Read-only cell. It's safe to use this in a static variable, but it's not safe
7// to mutate it. This is useful for storing static data that is expensive to
8// initialize, but is immutable once.
9pub struct RoCell<T>(UnsafeCell<Option<T>>);
10
11unsafe impl<T> Sync for RoCell<T> {}
12
13impl<T> RoCell<T> {
14    #[inline]
15    pub const fn new() -> Self {
16        Self(UnsafeCell::new(None))
17    }
18
19    #[inline]
20    pub fn init(&self, value: T) {
21        unsafe {
22            *self.0.get() = Some(value);
23        }
24    }
25
26    #[inline]
27    pub fn with<F>(&self, f: F)
28    where
29        F: FnOnce() -> T,
30    {
31        self.init(f());
32    }
33}
34
35impl<T> AsRef<T> for RoCell<T> {
36    fn as_ref(&self) -> &T {
37        unsafe { (*self.0.get()).as_ref().unwrap() }
38    }
39}
40
41impl<T> Display for RoCell<T>
42where
43    T: Display,
44{
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        self.as_ref().fmt(f)
47    }
48}