cursed/
inout.rs

1use core::ffi::c_void;
2use core::ptr::NonNull;
3use alloc::sync::Arc;
4
5#[repr(transparent)]
6#[derive(Debug)]
7pub struct In<T>(*const T);
8unsafe impl<T> Sync for In<T> {}
9unsafe impl<T> Send for In<T> {}
10
11impl<T> In<T> {
12    #[inline]
13    pub fn is_null(&self) -> bool {
14        self.0.is_null()
15    }
16
17    #[inline]
18    pub fn as_ptr(&self) -> Option<NonNull<T>> {
19        NonNull::new(self.0 as *mut _)
20    }
21
22    #[inline]
23    pub unsafe fn as_ref(&self) -> Option<&T> {
24        match self.is_null() {
25            false => Some(&*self.0),
26            true => None,
27        }
28    }
29}
30
31#[doc(hidden)]
32fn as_arc_internal<T, U>(arc: &In<U>) -> Option<Arc<T>> {
33    if let Some(arc) = arc.as_ptr() {
34        let arc = unsafe { Arc::from_raw(arc.as_ptr() as *const _) };
35        let arc1: Arc<T> = Arc::clone(&arc);
36        core::mem::forget(arc);
37        Some(arc1)
38    } else {
39        None
40    }
41}
42
43impl<T> In<Arc<T>> {
44    pub fn as_arc(&self) -> Option<Arc<T>> {
45        as_arc_internal(self)
46    }
47}
48
49impl<T> In<crate::sync::ArcPtr<T>> {
50    pub fn as_arc(&self) -> Option<Arc<T>> {
51        as_arc_internal(self)
52    }
53}
54
55#[repr(transparent)]
56#[derive(Debug)]
57pub struct Out<T>(*mut T);
58unsafe impl<T> Sync for Out<T> {}
59unsafe impl<T> Send for Out<T> {}
60
61impl<T> Out<T> {
62    #[inline]
63    pub fn is_null(&self) -> bool {
64        self.0.is_null()
65    }
66
67    #[inline]
68    pub fn as_ptr(&self) -> Option<NonNull<T>> {
69        NonNull::new(self.0)
70    }
71
72    #[inline]
73    pub unsafe fn as_mut_ref(&mut self) -> Option<&mut T> {
74        match self.is_null() {
75            false => Some(&mut *self.0),
76            true => None,
77        }
78    }
79}
80
81#[repr(transparent)]
82#[derive(Debug)]
83pub struct OutPtr<T>(*mut *mut T);
84unsafe impl<T> Sync for OutPtr<T> {}
85unsafe impl<T> Send for OutPtr<T> {}
86
87impl<T> OutPtr<T> {
88    #[inline]
89    pub fn is_null(&self) -> bool {
90        self.0.is_null()
91    }
92
93    #[inline]
94    pub fn as_ptr(&self) -> Option<NonNull<*mut T>> {
95        NonNull::new(self.0)
96    }
97
98    #[inline]
99    pub unsafe fn as_mut_ref(&mut self) -> Option<&mut *mut T> {
100        match self.is_null() {
101            false => Some(&mut *self.0),
102            true => None,
103        }
104    }
105}
106
107#[repr(transparent)]
108#[derive(Debug)]
109pub struct InOut<T>(*mut T);
110unsafe impl<T> Sync for InOut<T> {}
111unsafe impl<T> Send for InOut<T> {}
112
113impl<T> InOut<T> {
114    #[inline]
115    pub fn is_null(&self) -> bool {
116        self.0.is_null()
117    }
118
119    #[inline]
120    pub fn as_ptr(&self) -> Option<NonNull<T>> {
121        NonNull::new(self.0)
122    }
123
124    #[inline]
125    pub unsafe fn as_ref(&self) -> Option<&T> {
126        match self.is_null() {
127            false => Some(&*self.0),
128            true => None,
129        }
130    }
131
132    #[inline]
133    pub unsafe fn as_mut_ref(&mut self) -> Option<&mut T> {
134        match self.is_null() {
135            false => Some(&mut *self.0),
136            true => None,
137        }
138    }
139
140    #[inline]
141    pub fn to_in(&self) -> In<T> {
142        In(self.0)
143    }
144
145    #[inline]
146    pub fn to_out(&self) -> Out<T> {
147        Out(self.0)
148    }
149}
150
151pub type InRaw = In<c_void>;
152pub type OutRaw = Out<c_void>;
153pub type InOutRaw = InOut<c_void>;