1use std::marker::PhantomData;
2use std::ops::{Deref, DerefMut};
3
4pub unsafe trait OpaquePtr {
22 type SysPointee;
23 type Pointee;
24}
25
26#[repr(transparent)]
30pub struct Ref<'a, P>
31where
32 P: OpaquePtr,
33{
34 ptr: *const P::SysPointee,
35 _o: PhantomData<&'a ()>,
36 _p: PhantomData<P::Pointee>,
37}
38
39impl<'a, P> Ref<'a, P>
40where
41 P: OpaquePtr,
42{
43 pub fn new(ptr: *const P::SysPointee) -> Ref<'a, P> {
44 Ref {
45 ptr,
46 _o: PhantomData,
47 _p: PhantomData,
48 }
49 }
50
51 pub fn as_ptr(&self) -> *const P::SysPointee {
52 self.ptr
53 }
54}
55
56#[repr(transparent)]
60pub struct RefMut<'a, P>
61where
62 P: OpaquePtr,
63{
64 ptr: *mut P::SysPointee,
65 _o: PhantomData<&'a ()>,
66 _p: PhantomData<P::Pointee>,
67}
68
69impl<'a, P> RefMut<'a, P>
70where
71 P: OpaquePtr,
72{
73 pub fn new(ptr: *mut P::SysPointee) -> RefMut<'a, P> {
74 RefMut {
75 ptr,
76 _o: PhantomData,
77 _p: PhantomData,
78 }
79 }
80
81 pub fn as_ptr(&self) -> *const P::SysPointee {
82 self.ptr
83 }
84
85 pub fn as_mut_ptr(&mut self) -> *mut P::SysPointee {
86 self.ptr
87 }
88}
89
90impl<'a, P> Deref for Ref<'a, P>
91where
92 P: OpaquePtr,
93{
94 type Target = P::Pointee;
95
96 fn deref(&self) -> &Self::Target {
97 unsafe {
98 &*(&self.ptr as *const *const <P as OpaquePtr>::SysPointee
99 as *const <P as OpaquePtr>::Pointee)
100 }
101 }
102}
103
104impl<'a, P> Deref for RefMut<'a, P>
105where
106 P: OpaquePtr,
107{
108 type Target = P::Pointee;
109
110 fn deref(&self) -> &Self::Target {
111 unsafe {
112 &*(&self.ptr as *const *mut <P as OpaquePtr>::SysPointee
113 as *const <P as OpaquePtr>::Pointee)
114 }
115 }
116}
117
118impl<'a, P> DerefMut for RefMut<'a, P>
119where
120 P: OpaquePtr,
121{
122 fn deref_mut(&mut self) -> &mut Self::Target {
123 unsafe {
124 &mut *(&mut self.ptr as *mut *mut <P as OpaquePtr>::SysPointee
125 as *mut <P as OpaquePtr>::Pointee)
126 }
127 }
128}
129
130impl<'a, P> AsRef<P::Pointee> for Ref<'a, P>
131where
132 P: OpaquePtr,
133{
134 fn as_ref(&self) -> &P::Pointee {
135 unsafe {
136 &*(&self.ptr as *const *const <P as OpaquePtr>::SysPointee
137 as *const <P as OpaquePtr>::Pointee)
138 }
139 }
140}
141