1use std::fmt::{Debug, Formatter};
2use std::mem::forget;
3use std::ops::Deref;
4use std::ptr::NonNull;
5
6use crate::Opaque;
7
8pub trait OpaqueDrop {
9 unsafe fn drop_raw(ptr: *mut Self);
10}
11
12pub trait OpaqueClone {
13 unsafe fn clone_raw(ptr: *mut Self) -> *mut Self;
14}
15
16pub struct Owning<T: Opaque<Inner: OpaqueDrop>> {
17 ptr: NonNull<T>,
18}
19
20impl<T: Opaque<Inner: OpaqueDrop + OpaqueClone>> Clone for Owning<T> {
21 fn clone(&self) -> Self {
22 unsafe { Self::from_raw(T::Inner::clone_raw(self.as_raw())) }
23 }
24}
25
26impl<T: Opaque<Inner: OpaqueDrop>> Drop for Owning<T> {
27 fn drop(&mut self) {
28 unsafe { T::Inner::drop_raw(self.as_raw()) }
29 }
30}
31
32impl<T: Opaque<Inner: OpaqueDrop>> Deref for Owning<T> {
33 type Target = T;
34
35 fn deref(&self) -> &Self::Target {
36 unsafe { self.ptr.as_ref() }
37 }
38}
39
40impl<T: Opaque<Inner: OpaqueDrop> + Debug> Debug for Owning<T> {
41 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42 Debug::fmt(self.deref(), f)
43 }
44}
45
46impl<T: Opaque<Inner: OpaqueDrop>> Owning<T> {
47 pub unsafe fn from_ptr(ptr: *mut T::Inner) -> Option<Self> {
48 if ptr.is_null() {
49 None
50 } else {
51 unsafe { Some(Self::from_raw(ptr)) }
52 }
53 }
54
55 pub unsafe fn from_raw(ptr: *mut T::Inner) -> Self {
56 unsafe {
57 Self {
58 ptr: T::from_raw(ptr).into(),
59 }
60 }
61 }
62
63 pub fn into_raw(self) -> *mut T::Inner {
64 let ptr = self.as_raw();
65 forget(self);
66 ptr
67 }
68}