rustrict/
feature_cell.rs

1#[cfg(feature = "customize")]
2use std::cell::UnsafeCell;
3use std::ops::Deref;
4
5/// Allows (unsafe) mutation if the "customize" feature is enabled. In this case, mutation must
6/// not be concurrent. Otherwise, 100% safe.
7pub(crate) struct FeatureCell<T> {
8    #[cfg(feature = "customize")]
9    inner: UnsafeCell<T>,
10    #[cfg(not(feature = "customize"))]
11    inner: T,
12}
13
14impl<T> FeatureCell<T> {
15    pub fn new(val: T) -> Self {
16        Self {
17            #[cfg(feature = "customize")]
18            inner: UnsafeCell::new(val),
19            #[cfg(not(feature = "customize"))]
20            inner: val,
21        }
22    }
23
24    /// SAFETY: Caller must avoid concurrent access, in accordance with documentation.
25    #[cfg(feature = "customize")]
26    pub unsafe fn get_mut(&self) -> &mut T {
27        &mut *self.inner.get()
28    }
29}
30
31impl<T> Deref for FeatureCell<T> {
32    type Target = T;
33
34    fn deref(&self) -> &Self::Target {
35        #[cfg(not(feature = "customize"))]
36        return &self.inner;
37        // SAFETY: User must avoid concurrent access, in accordance with documentation.
38        #[cfg(feature = "customize")]
39        unsafe {
40            &*self.inner.get()
41        }
42    }
43}
44
45// SAFETY: User must avoid concurrent access, in accordance with documentation.
46#[cfg(feature = "customize")]
47unsafe impl<T> Send for FeatureCell<T> {}
48unsafe impl<T> Sync for FeatureCell<T> {}