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}