pluginop_rawptr/
lib.rs

1//! An internal crate to offer a safe interface over raw pointers
2//! to **pinned** types.
3
4use std::{
5    fmt::{Debug, Pointer},
6    io::Cursor,
7    ops::{Deref, DerefMut},
8};
9
10/// A raw pointer to a pinned structure that is `!Unpin`.
11pub struct RawPtr<T: ?Sized> {
12    inner: *const T,
13}
14
15#[allow(dead_code)]
16impl<T: ?Sized> RawPtr<T> {
17    /// Creates a new raw pointer to `T`.
18    ///
19    /// SAFETY: While this method is safe per se, the whole safety of all the methods of the
20    /// `RawPtr` wrapper relies on `ptr` referencing a pinned structure that is `!Unpin`.
21    pub fn new(ptr: *const T) -> Self {
22        Self { inner: ptr }
23    }
24
25    /// Returns whether the underlying raw pointer is `NULL`.
26    pub fn is_null(&self) -> bool {
27        self.inner.is_null()
28    }
29}
30
31impl<T: ?Sized> Clone for RawPtr<T> {
32    fn clone(&self) -> Self {
33        *self
34    }
35}
36
37impl<T: ?Sized> Copy for RawPtr<T> {}
38
39impl<T: ?Sized> Deref for RawPtr<T> {
40    type Target = *const T;
41
42    fn deref(&self) -> &Self::Target {
43        &self.inner
44    }
45}
46
47impl<T: ?Sized> PartialEq for RawPtr<T> {
48    fn eq(&self, other: &Self) -> bool {
49        std::ptr::eq(self.inner, other.inner)
50    }
51}
52
53#[allow(dead_code)]
54impl<T: Sized> RawPtr<T> {
55    pub fn null() -> Self {
56        Self {
57            inner: std::ptr::null(),
58        }
59    }
60
61    pub fn ptr_eq(&self, ptr: *const T) -> bool {
62        std::ptr::eq(self.inner, ptr)
63    }
64}
65
66impl<T: ?Sized> Debug for RawPtr<T> {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        Pointer::fmt(&self.inner, f)
69    }
70}
71
72// SAFETY: Only safe if T is pinned. In the current code, we only use this type on pinned variables.
73unsafe impl<T: ?Sized> Send for RawPtr<T> {}
74
75// SAFETY: Only safe if T is pinned. In the current code, we only use this type on pinned variables.
76unsafe impl<T: ?Sized> Sync for RawPtr<T> {}
77
78/// A raw mutable pointer to a pinned structure that is `!Unpin`.
79pub struct RawMutPtr<T: ?Sized> {
80    inner: *mut T,
81}
82
83impl<T: ?Sized> RawMutPtr<T> {
84    /// Creates a new raw mutable pointer to `T`.
85    ///
86    /// SAFETY: While this method is safe per se, the whole safety of all the methods of the
87    /// `RawMutPtr` wrapper relies on `ptr` referencing a pinned structure that is `!Unpin`.
88    pub fn new(ptr: *mut T) -> Self {
89        Self { inner: ptr }
90    }
91
92    /// Returns whether the underlying raw pointer is `NULL`.
93    pub fn is_null(&self) -> bool {
94        self.inner.is_null()
95    }
96}
97
98impl<T: ?Sized> Clone for RawMutPtr<T> {
99    fn clone(&self) -> Self {
100        *self
101    }
102}
103
104impl<T: ?Sized> Copy for RawMutPtr<T> {}
105
106impl<T: ?Sized> Deref for RawMutPtr<T> {
107    type Target = *mut T;
108
109    fn deref(&self) -> &Self::Target {
110        &self.inner
111    }
112}
113
114impl<T: ?Sized> DerefMut for RawMutPtr<T> {
115    fn deref_mut(&mut self) -> &mut Self::Target {
116        &mut self.inner
117    }
118}
119
120impl<T: ?Sized> PartialEq for RawMutPtr<T> {
121    fn eq(&self, other: &Self) -> bool {
122        std::ptr::eq(self.inner, other.inner)
123    }
124}
125
126impl<T: Sized> RawMutPtr<T> {
127    pub fn null() -> Self {
128        Self {
129            inner: std::ptr::null_mut(),
130        }
131    }
132
133    pub fn ptr_eq(&self, ptr: *mut T) -> bool {
134        std::ptr::eq(self.inner, ptr)
135    }
136}
137
138impl<T: ?Sized> Debug for RawMutPtr<T> {
139    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
140        Pointer::fmt(&self.inner, f)
141    }
142}
143
144// SAFETY: Only safe if T is pinned AND if the underlying reference is not moved out. In the
145// current code, we only use this type on pinned variables.
146unsafe impl<T: ?Sized> Send for RawMutPtr<T> {}
147
148// SAFETY: Only safe if T is pinned AND if the underlying reference is not moved out. In the
149// current code, we only use this type on pinned variables.
150unsafe impl<T: ?Sized> Sync for RawMutPtr<T> {}
151
152use bytes::{Bytes, BytesMut};
153
154/// A (safe) wrapper over a raw pointer to [`Cursor<Bytes>`]
155#[derive(Debug)]
156pub struct CursorBytesPtr(RawMutPtr<Cursor<Bytes>>);
157
158impl Deref for CursorBytesPtr {
159    type Target = Cursor<Bytes>;
160
161    fn deref(&self) -> &Self::Target {
162        // SAFETY: Valid only if `Cursor` is pinned and in single-thread.
163        unsafe { &**self.0 }
164    }
165}
166
167impl DerefMut for CursorBytesPtr {
168    fn deref_mut(&mut self) -> &mut Self::Target {
169        // SAFETY: Valid only if `Cursor` is pinned and in single-thread.
170        unsafe { &mut **self.0 }
171    }
172}
173
174impl From<&mut Cursor<Bytes>> for CursorBytesPtr {
175    fn from(value: &mut Cursor<Bytes>) -> Self {
176        // Don't forget the memory here since we have only a reference.
177        CursorBytesPtr(RawMutPtr::new(value as *const _ as *mut _))
178    }
179}
180
181/// A (safe) wrapper over a raw pointer to [`BytesMut`].
182#[derive(Debug)]
183pub struct BytesMutPtr(RawMutPtr<BytesMut>);
184
185impl Deref for BytesMutPtr {
186    type Target = BytesMut;
187
188    fn deref(&self) -> &Self::Target {
189        // SAFETY: Valid only if `BytesMut` is pinned and in single-thread.
190        unsafe { &**self.0 }
191    }
192}
193
194impl DerefMut for BytesMutPtr {
195    fn deref_mut(&mut self) -> &mut Self::Target {
196        // SAFETY: Valid only if `BytesMut` is pinned and in single-thread.
197        unsafe { &mut **self.0 }
198    }
199}
200
201impl From<&mut BytesMut> for BytesMutPtr {
202    fn from(value: &mut BytesMut) -> Self {
203        // Don't forget the memory here since we have only a reference.
204        BytesMutPtr(RawMutPtr::new(value as *const _ as *mut _))
205    }
206}