1use std::any::Any;
2use std::ffi::c_void;
3use std::mem::size_of;
4use std::ptr::NonNull;
5
6use crate::{BoxerError, Result};
7
8#[repr(transparent)]
9pub struct ErasedBorrowedPtr {
10 ptr: *mut c_void,
11}
12
13impl ErasedBorrowedPtr {
14 pub const unsafe fn from_raw(ptr: *mut c_void) -> Self {
19 Self { ptr }
20 }
21
22 pub const fn null() -> Self {
23 Self {
24 ptr: std::ptr::null_mut(),
25 }
26 }
27
28 pub const fn as_raw(&self) -> *mut c_void {
29 self.ptr
30 }
31
32 pub fn is_null(&self) -> bool {
33 self.ptr.is_null()
34 }
35
36 pub fn with_ptr<R: Any, F>(&self, op: F) -> Result<R>
37 where
38 F: FnOnce(NonNull<c_void>) -> Result<R>,
39 {
40 let pointer = NonNull::new(self.ptr)
41 .ok_or_else(|| BoxerError::NullPointer("erased borrowed ptr".to_string()))?;
42 op(pointer)
43 }
44
45 pub fn with_ptr_ok<R: Any, F>(&self, op: F) -> Result<R>
46 where
47 F: FnOnce(NonNull<c_void>) -> R,
48 {
49 self.with_ptr(|pointer| Ok(op(pointer)))
50 }
51}
52
53impl Default for ErasedBorrowedPtr {
54 fn default() -> Self {
55 Self::null()
56 }
57}
58
59pub unsafe fn from_raw<T>(pointer: *mut T) -> Box<T> {
66 assert!(!pointer.is_null(), "from_raw(): Pointer must not be null!");
67 assert_eq!(
68 size_of::<*mut T>(),
69 size_of::<*mut c_void>(),
70 "The pointer must be compatible with void*"
71 );
72 unsafe { Box::from_raw(pointer) }
73}
74
75pub fn into_raw<T>(boxed: Box<T>) -> *mut T {
76 assert_eq!(
77 size_of::<*mut T>(),
78 size_of::<*mut c_void>(),
79 "The pointer must be compatible with void*"
80 );
81 Box::into_raw(boxed)
82}