rune/runtime/
ref.rs

1use core::fmt;
2use core::future::Future;
3use core::ops::{Deref, DerefMut};
4use core::pin::Pin;
5use core::ptr::NonNull;
6use core::task::{Context, Poll};
7
8#[cfg(feature = "alloc")]
9use ::rust_alloc::rc::Rc;
10#[cfg(feature = "alloc")]
11use ::rust_alloc::sync::Arc;
12
13pub(super) struct RefVtable {
14    pub(super) drop: DropFn,
15}
16
17type DropFn = unsafe fn(NonNull<()>);
18
19/// A strong owned reference to the given type that can be safely dereferenced.
20///
21/// # Examples
22///
23/// Constructed from a static value:
24///
25/// ```rust
26/// use rune::Ref;
27///
28/// let value: Ref<str> = Ref::from_static("hello world");
29/// ```
30pub struct Ref<T: ?Sized> {
31    value: NonNull<T>,
32    guard: RawAnyGuard,
33}
34
35#[cfg(feature = "alloc")]
36impl<T> From<Rc<T>> for Ref<T> {
37    /// Construct from an atomically reference-counted value.
38    ///
39    /// # Examples
40    ///
41    /// ```
42    /// use std::rc::Rc;
43    /// use rune::Ref;
44    ///
45    /// let value: Ref<String> = Ref::from(Rc::new(String::from("hello world")));
46    /// assert_eq!(value.as_ref(), "hello world");
47    /// ```
48    fn from(value: Rc<T>) -> Ref<T> {
49        unsafe fn drop_fn<T>(data: NonNull<()>) {
50            let _ = Rc::from_raw(data.cast::<T>().as_ptr().cast_const());
51        }
52
53        let value = Rc::into_raw(value);
54        let value = unsafe { NonNull::new_unchecked(value as *mut _) };
55
56        let guard = RawAnyGuard::new(value.cast(), &RefVtable { drop: drop_fn::<T> });
57
58        Ref::new(value, guard)
59    }
60}
61
62#[cfg(feature = "alloc")]
63impl<T> From<Arc<T>> for Ref<T> {
64    /// Construct from an atomically reference-counted value.
65    ///
66    /// # Examples
67    ///
68    /// ```
69    /// use std::sync::Arc;
70    /// use rune::Ref;
71    ///
72    /// let value: Ref<String> = Ref::from(Arc::new(String::from("hello world")));
73    /// assert_eq!(value.as_ref(), "hello world");
74    /// ```
75    fn from(value: Arc<T>) -> Ref<T> {
76        unsafe fn drop_fn<T>(data: NonNull<()>) {
77            let _ = Arc::from_raw(data.cast::<T>().as_ptr().cast_const());
78        }
79
80        let value = Arc::into_raw(value);
81        let value = unsafe { NonNull::new_unchecked(value as *mut _) };
82
83        let guard = RawAnyGuard::new(value.cast(), &RefVtable { drop: drop_fn::<T> });
84
85        Ref::new(value, guard)
86    }
87}
88
89impl<T: ?Sized> Ref<T> {
90    pub(super) const fn new(value: NonNull<T>, guard: RawAnyGuard) -> Self {
91        Self { value, guard }
92    }
93
94    /// Construct an owned reference from a static value.
95    ///
96    /// # Examples
97    ///
98    /// ```rust
99    /// use rune::Ref;
100    ///
101    /// let value: Ref<str> = Ref::from_static("Hello World");
102    /// assert_eq!(value.as_ref(), "Hello World");
103    /// ```
104    pub const fn from_static(value: &'static T) -> Ref<T> {
105        let value = unsafe { NonNull::new_unchecked((value as *const T).cast_mut()) };
106        let guard = RawAnyGuard::new(NonNull::dangling(), &RefVtable { drop: |_| {} });
107        Self::new(value, guard)
108    }
109
110    /// Map the interior reference of an owned mutable value.
111    ///
112    /// # Examples
113    ///
114    /// ```
115    /// use rune::Ref;
116    /// use rune::runtime::Bytes;
117    /// use rune::alloc::try_vec;
118    ///
119    /// let bytes = rune::to_value(Bytes::from_vec(try_vec![1, 2, 3, 4]))?;
120    /// let bytes: Ref<Bytes> = rune::from_value(bytes)?;
121    /// let value: Ref<[u8]> = Ref::map(bytes, |vec| &vec[0..2]);
122    ///
123    /// assert_eq!(&*value, &[1, 2][..]);
124    /// # Ok::<_, rune::support::Error>(())
125    /// ```
126    #[inline]
127    pub fn map<U: ?Sized, F>(this: Self, f: F) -> Ref<U>
128    where
129        F: FnOnce(&T) -> &U,
130    {
131        let Self { value, guard } = this;
132
133        // Safety: this follows the same safety guarantees as when the managed
134        // ref was acquired. And since we have a managed reference to `T`, we're
135        // permitted to do any sort of projection to `U`.
136        let value = f(unsafe { value.as_ref() });
137
138        Ref::new(value.into(), guard)
139    }
140
141    /// Try to map the reference to a projection.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// use rune::Ref;
147    /// use rune::runtime::Bytes;
148    /// use rune::alloc::try_vec;
149    ///
150    /// let bytes = rune::to_value(Bytes::from_vec(try_vec![1, 2, 3, 4]))?;
151    /// let bytes: Ref<Bytes> = rune::from_value(bytes)?;
152    ///
153    /// let Ok(value) = Ref::try_map(bytes, |bytes| bytes.get(0..2)) else {
154    ///     panic!("Conversion failed");
155    /// };
156    ///
157    /// assert_eq!(&value[..], &[1, 2][..]);
158    /// # Ok::<_, rune::support::Error>(())
159    /// ```
160    #[inline]
161    pub fn try_map<U: ?Sized, F>(this: Self, f: F) -> Result<Ref<U>, Ref<T>>
162    where
163        F: FnOnce(&T) -> Option<&U>,
164    {
165        let Self { value, guard } = this;
166
167        // Safety: this follows the same safety guarantees as when the managed
168        // ref was acquired. And since we have a managed reference to `T`, we're
169        // permitted to do any sort of projection to `U`.
170
171        unsafe {
172            let Some(value) = f(value.as_ref()) else {
173                return Err(Ref::new(value, guard));
174            };
175
176            Ok(Ref::new(value.into(), guard))
177        }
178    }
179
180    /// Convert into a raw pointer and associated raw access guard.
181    ///
182    /// # Safety
183    ///
184    /// The returned pointer must not outlive the associated guard, since this
185    /// prevents other uses of the underlying data which is incompatible with
186    /// the current.
187    pub fn into_raw(this: Self) -> (NonNull<T>, RawAnyGuard) {
188        (this.value, this.guard)
189    }
190
191    /// Convert a raw reference and guard into a regular reference.
192    ///
193    /// # Safety
194    ///
195    /// The caller is responsible for ensuring that the raw reference is
196    /// associated with the specific pointer.
197    pub unsafe fn from_raw(value: NonNull<T>, guard: RawAnyGuard) -> Self {
198        Self { value, guard }
199    }
200}
201
202impl<T: ?Sized> AsRef<T> for Ref<T> {
203    #[inline]
204    fn as_ref(&self) -> &T {
205        self
206    }
207}
208
209impl<T: ?Sized> Deref for Ref<T> {
210    type Target = T;
211
212    #[inline]
213    fn deref(&self) -> &Self::Target {
214        // Safety: An owned ref holds onto a hard pointer to the data,
215        // preventing it from being dropped for the duration of the owned ref.
216        unsafe { self.value.as_ref() }
217    }
218}
219
220impl<T: ?Sized> fmt::Debug for Ref<T>
221where
222    T: fmt::Debug,
223{
224    #[inline]
225    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
226        fmt::Debug::fmt(&**self, fmt)
227    }
228}
229
230/// A strong owned mutable reference to the given type that can be safely
231/// dereferenced.
232///
233/// # Examples
234///
235/// Constructed from a static value:
236///
237/// ```rust
238/// use rune::Mut;
239///
240/// let value: Mut<[u8]> = Mut::from_static(&mut [][..]);
241/// assert_eq!(&value[..], b"");
242/// ```
243pub struct Mut<T: ?Sized> {
244    value: NonNull<T>,
245    guard: RawAnyGuard,
246}
247
248impl<T: ?Sized> Mut<T> {
249    pub(super) const fn new(value: NonNull<T>, guard: RawAnyGuard) -> Self {
250        Self { value, guard }
251    }
252
253    /// Construct an owned mutable reference from a static value.
254    ///
255    /// # Examples
256    ///
257    /// ```rust
258    /// use rune::Mut;
259    ///
260    /// let value: Mut<[u8]> = Mut::from_static(&mut [][..]);
261    /// assert_eq!(&value[..], b"");
262    /// ```
263    pub fn from_static(value: &'static mut T) -> Mut<T> {
264        let value = unsafe { NonNull::new_unchecked((value as *const T).cast_mut()) };
265        let guard = RawAnyGuard::new(NonNull::dangling(), &RefVtable { drop: |_| {} });
266        Self::new(value, guard)
267    }
268
269    /// Map the interior reference of an owned mutable value.
270    ///
271    /// # Examples
272    ///
273    /// ```
274    /// use rune::Mut;
275    /// use rune::runtime::Bytes;
276    /// use rune::alloc::try_vec;
277    ///
278    /// let bytes = rune::to_value(Bytes::from_vec(try_vec![1, 2, 3, 4]))?;
279    /// let bytes: Mut<Bytes> = rune::from_value(bytes)?;
280    /// let value: Mut<[u8]> = Mut::map(bytes, |bytes| &mut bytes[0..2]);
281    ///
282    /// assert_eq!(&*value, &mut [1, 2][..]);
283    /// # Ok::<_, rune::support::Error>(())
284    /// ```
285    pub fn map<U: ?Sized, F>(this: Self, f: F) -> Mut<U>
286    where
287        F: FnOnce(&mut T) -> &mut U,
288    {
289        let Self {
290            mut value, guard, ..
291        } = this;
292
293        // Safety: this follows the same safety guarantees as when the managed
294        // ref was acquired. And since we have a managed reference to `T`, we're
295        // permitted to do any sort of projection to `U`.
296        let value = f(unsafe { value.as_mut() });
297
298        Mut::new(value.into(), guard)
299    }
300
301    /// Try to map the mutable reference to a projection.
302    ///
303    /// # Examples
304    ///
305    /// ```
306    /// use rune::Mut;
307    /// use rune::runtime::Bytes;
308    /// use rune::alloc::try_vec;
309    ///
310    /// let bytes = rune::to_value(Bytes::from_vec(try_vec![1, 2, 3, 4]))?;
311    /// let bytes: Mut<Bytes> = rune::from_value(bytes)?;
312    ///
313    /// let Ok(mut value) = Mut::try_map(bytes, |bytes| bytes.get_mut(0..2)) else {
314    ///     panic!("Conversion failed");
315    /// };
316    ///
317    /// assert_eq!(&mut value[..], &mut [1, 2][..]);
318    /// # Ok::<_, rune::support::Error>(())
319    /// ```
320    #[inline]
321    pub fn try_map<U: ?Sized, F>(this: Self, f: F) -> Result<Mut<U>, Mut<T>>
322    where
323        F: FnOnce(&mut T) -> Option<&mut U>,
324    {
325        let Self {
326            mut value, guard, ..
327        } = this;
328
329        // Safety: this follows the same safety guarantees as when the managed
330        // ref was acquired. And since we have a managed reference to `T`, we're
331        // permitted to do any sort of projection to `U`.
332        unsafe {
333            let Some(value) = f(value.as_mut()) else {
334                return Err(Mut::new(value, guard));
335            };
336
337            Ok(Mut::new(value.into(), guard))
338        }
339    }
340
341    /// Convert into a raw pointer and associated raw access guard.
342    ///
343    /// # Safety
344    ///
345    /// The returned pointer must not outlive the associated guard, since this
346    /// prevents other uses of the underlying data which is incompatible with
347    /// the current.
348    pub fn into_raw(this: Self) -> (NonNull<T>, RawAnyGuard) {
349        (this.value, this.guard)
350    }
351
352    /// Convert a raw mutable reference and guard into a regular mutable
353    /// reference.
354    ///
355    /// # Safety
356    ///
357    /// The caller is responsible for ensuring that the raw mutable reference is
358    /// associated with the specific pointer.
359    pub unsafe fn from_raw(value: NonNull<T>, guard: RawAnyGuard) -> Self {
360        Self { value, guard }
361    }
362}
363
364impl<T: ?Sized> AsRef<T> for Mut<T> {
365    #[inline]
366    fn as_ref(&self) -> &T {
367        self
368    }
369}
370
371impl<T: ?Sized> AsMut<T> for Mut<T> {
372    #[inline]
373    fn as_mut(&mut self) -> &mut T {
374        self
375    }
376}
377
378impl<T: ?Sized> Deref for Mut<T> {
379    type Target = T;
380
381    fn deref(&self) -> &Self::Target {
382        // Safety: An owned mut holds onto a hard pointer to the data,
383        // preventing it from being dropped for the duration of the owned mut.
384        unsafe { self.value.as_ref() }
385    }
386}
387
388impl<T: ?Sized> DerefMut for Mut<T> {
389    fn deref_mut(&mut self) -> &mut Self::Target {
390        // Safety: An owned mut holds onto a hard pointer to the data,
391        // preventing it from being dropped for the duration of the owned mut.
392        unsafe { self.value.as_mut() }
393    }
394}
395
396impl<T: ?Sized> fmt::Debug for Mut<T>
397where
398    T: fmt::Debug,
399{
400    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
401        fmt::Debug::fmt(&**self, fmt)
402    }
403}
404
405impl<F> Future for Mut<F>
406where
407    F: Unpin + Future,
408{
409    type Output = F::Output;
410
411    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
412        // NB: inner Future is Unpin.
413        let this = self.get_mut();
414        Pin::new(&mut **this).poll(cx)
415    }
416}
417
418/// A raw guard for a [`Ref`] or a [`Mut`] that has been converted into its raw
419/// components through [`Ref::into_raw`] or [`Mut::into_raw`].
420pub struct RawAnyGuard {
421    data: NonNull<()>,
422    vtable: &'static RefVtable,
423}
424
425impl RawAnyGuard {
426    pub(super) const fn new(data: NonNull<()>, vtable: &'static RefVtable) -> Self {
427        Self { data, vtable }
428    }
429}
430
431impl Drop for RawAnyGuard {
432    fn drop(&mut self) {
433        // Safety: type and referential safety is guaranteed at construction
434        // time, since all constructors are unsafe.
435        unsafe {
436            (self.vtable.drop)(self.data);
437        }
438    }
439}