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 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}