genet_abi/
fixed.rs

1//! Fixed-lifetime shareable containers.
2
3use std::{
4    fmt, mem,
5    ops::{Deref, DerefMut},
6    ptr::NonNull,
7};
8
9/// A fixed memory location.
10#[repr(C)]
11#[derive(Copy)]
12pub struct Fixed<T> {
13    ptr: NonNull<T>,
14}
15
16unsafe impl<T: Send> Send for Fixed<T> {}
17unsafe impl<T: Sync> Sync for Fixed<T> {}
18
19impl<T> fmt::Debug for Fixed<T> {
20    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21        write!(f, "Fixed {:?}", self.ptr)
22    }
23}
24
25impl<T> Clone for Fixed<T> {
26    fn clone(&self) -> Fixed<T> {
27        Self {
28            ptr: unsafe { NonNull::new_unchecked(self.ptr.as_ptr()) },
29        }
30    }
31}
32
33impl<T> Fixed<T> {
34    /// Creates a new Fixed containing the given value.
35    pub fn new(data: T) -> Fixed<T> {
36        Self {
37            ptr: unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(data))) },
38        }
39    }
40
41    /// Creates a new Fixed from the given static value.
42    pub fn from_static(data: &'static T) -> Fixed<T> {
43        Self {
44            ptr: unsafe { NonNull::new_unchecked(mem::transmute(data)) },
45        }
46    }
47
48    /// Returns a raw pointer to the underlying data in this container.
49    pub fn as_ptr(&self) -> *const T {
50        self.ptr.as_ptr()
51    }
52}
53
54impl<T, D: Deref<Target = T>> From<&'static D> for Fixed<T> {
55    fn from(data: &'static D) -> Fixed<T> {
56        Self {
57            ptr: unsafe { NonNull::new_unchecked(mem::transmute(data.deref())) },
58        }
59    }
60}
61
62impl<T> AsRef<T> for Fixed<T> {
63    fn as_ref(&self) -> &T {
64        unsafe { self.ptr.as_ref() }
65    }
66}
67
68impl<T> Deref for Fixed<T> {
69    type Target = T;
70
71    fn deref(&self) -> &T {
72        self.as_ref()
73    }
74}
75
76/// A mutable fixed memory location.
77#[repr(C)]
78pub struct MutFixed<T> {
79    ptr: NonNull<T>,
80}
81
82unsafe impl<T: Send> Send for MutFixed<T> {}
83
84impl<T> fmt::Debug for MutFixed<T> {
85    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
86        write!(f, "MutFixed {:?}", self.ptr)
87    }
88}
89
90impl<T> MutFixed<T> {
91    /// Creates a new MutFixed containing the given value.
92    pub fn new(data: T) -> MutFixed<T> {
93        Self {
94            ptr: unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(data))) },
95        }
96    }
97
98    /// Returns a raw pointer to the underlying data in this container.
99    pub fn as_ptr(&self) -> *const T {
100        self.ptr.as_ptr()
101    }
102
103    /// Returns a mutable raw pointer to the underlying data in this container.
104    pub fn as_mut_ptr(&self) -> *mut T {
105        self.ptr.as_ptr()
106    }
107
108    pub unsafe fn from_ptr(ptr: *mut T) -> MutFixed<T> {
109        Self {
110            ptr: NonNull::new_unchecked(ptr),
111        }
112    }
113}
114
115impl<T> Deref for MutFixed<T> {
116    type Target = T;
117
118    fn deref(&self) -> &T {
119        unsafe { self.ptr.as_ref() }
120    }
121}
122
123impl<T> DerefMut for MutFixed<T> {
124    fn deref_mut(&mut self) -> &mut T {
125        unsafe { self.ptr.as_mut() }
126    }
127}
128
129#[cfg(test)]
130mod tests {
131    use super::*;
132
133    #[test]
134    fn new() {
135        let data = 123u32;
136        let ptr = Fixed::new(data);
137        assert_eq!(*ptr, data);
138    }
139}