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