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}