Skip to main content

value_box/
owned.rs

1use std::any::{Any, type_name};
2use std::mem::ManuallyDrop;
3
4use crate::erased::{from_raw, into_raw};
5use crate::{BoxerError, Result};
6
7#[must_use]
8#[repr(transparent)]
9pub struct OwnedPtr<T: Any> {
10    ptr: *mut T,
11}
12
13impl<T: Any> OwnedPtr<T> {
14    pub fn new(value: T) -> Self {
15        Self {
16            ptr: into_raw(Box::new(value)),
17        }
18    }
19
20    /// # Safety
21    ///
22    /// `ptr` must be uniquely owned, created by `Box::into_raw(Box<T>)` for the
23    /// same `T`, and must not have already been reclaimed.
24    pub const unsafe fn from_raw(ptr: *mut T) -> Self {
25        Self { ptr }
26    }
27
28    pub const fn null() -> Self {
29        Self {
30            ptr: std::ptr::null_mut(),
31        }
32    }
33
34    pub fn is_null(&self) -> bool {
35        self.ptr.is_null()
36    }
37
38    pub fn with_value<R: Any, F>(self, op: F) -> Result<R>
39    where
40        F: FnOnce(T) -> Result<R>,
41    {
42        self.into_value().and_then(op)
43    }
44
45    pub fn with_value_ok<R: Any, F>(self, op: F) -> Result<R>
46    where
47        F: FnOnce(T) -> R,
48    {
49        self.with_value(|value| Ok(op(value)))
50    }
51
52    fn into_value(self) -> Result<T> {
53        let pointer = self.into_ptr();
54        if pointer.is_null() {
55            return BoxerError::NullPointer(type_name::<T>().to_string()).into();
56        }
57
58        Ok(unsafe { *from_raw(pointer) })
59    }
60
61    fn into_ptr(self) -> *mut T {
62        let this = ManuallyDrop::new(self);
63        this.ptr
64    }
65}
66
67impl<T: Any> Default for OwnedPtr<T> {
68    fn default() -> Self {
69        Self::null()
70    }
71}
72
73impl<T: Any> From<T> for OwnedPtr<T> {
74    fn from(value: T) -> Self {
75        Self::new(value)
76    }
77}
78
79impl<T: Any> Drop for OwnedPtr<T> {
80    fn drop(&mut self) {
81        if self.ptr.is_null() {
82            return;
83        }
84
85        unsafe {
86            drop(from_raw(self.ptr));
87        }
88    }
89}