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}