unsafe_storage/
lib.rs

1use std::ops::Deref;
2
3/// [UnsafeStorage] is used to mark that there are some arbitrary invariants
4/// which must be maintained in storing its inner value. Therefore, creation and
5/// modifying of the inner value is an "unsafe" behavior. Although it might not
6/// be unsafe in traditional Rust terms (no memory unsafety), behavior might be
7/// "undefined"—or at least undocumented, because invariants are expected to be
8/// upheld.
9///
10/// This is useful in macros which do not encapsulate their storage in modules.
11/// This makes the macros for the end-user more ergonomic, as they can use the
12/// macro multiple times in a single module.
13#[repr(transparent)]
14#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Ord, Hash, Default)]
15pub struct UnsafeStorage<T>(T);
16
17impl<T> UnsafeStorage<T> {
18    /// # Safety
19    /// - See the broader scope that this is called in and which invariants are
20    ///   mentioned
21    pub unsafe fn new_unsafe(inner: T) -> Self {
22        Self(inner)
23    }
24
25    /// # Safety
26    /// This should be a safe operation assuming that when modifying T to T',
27    /// UnsafeStorage::new_unsafe(T') is safe
28    pub unsafe fn as_ref_mut(&mut self) -> &mut T {
29        &mut self.0
30    }
31}
32
33impl<T: Copy> UnsafeStorage<T> {
34    /// Get the inner value
35    pub fn inner(&self) -> T {
36        self.0
37    }
38}
39
40impl <T> Deref for UnsafeStorage<T> {
41    type Target = T;
42
43    fn deref(&self) -> &Self::Target {
44        &self.0
45    }
46}