1 | //! FFI interoperability for skia-safe's wrapper types. |
2 | //! |
3 | //! This module is only meant to be used by external code. Internal code should continue to use the traits in |
4 | //! the `prelude` module. |
5 | use crate::prelude::*; |
6 | |
7 | /// This trait supports the conversion of a wrapper into it's wrapped C/C++ pointer and back. |
8 | /// |
9 | /// The wrapped value can be accessed through the functions `inner` and `inner_mut`. |
10 | /// |
11 | /// # Safety |
12 | /// |
13 | /// The native value `N` _should_ be treated as opaque, because its definition may change |
14 | /// without adhering to semantic versioning and depends on what the tool bindgen is able to generate. |
15 | /// |
16 | /// Converting from a Rust wrapper to the wrapped value loses the automatic ability to free associated resources. |
17 | pub unsafe trait PointerWrapper<N> |
18 | where |
19 | Self: Sized, |
20 | { |
21 | /// Wraps a native pointer into a wrapper type. |
22 | /// Returns `None` if the pointer is `null`. |
23 | fn wrap(ptr: *mut N) -> Option<Self>; |
24 | /// Unwraps the wrapper type into the native pointer. |
25 | fn unwrap(self) -> *mut N; |
26 | /// Access the wrapped pointer. |
27 | fn inner(&self) -> &N; |
28 | /// Access the wrapped pointer. |
29 | fn inner_mut(&mut self) -> &mut N; |
30 | } |
31 | |
32 | /// A trait that supports the conversion from a C/C++ value into its Rust wrapper and back. |
33 | /// |
34 | /// The wrapped value can be accessed through the functions `inner` and `inner_mut`. |
35 | /// |
36 | /// This trait is implemented for all wrapper types that manage C++/C values in Rust without an pointer indirection. |
37 | /// |
38 | /// # Safety |
39 | /// |
40 | /// The native type `N` _should_ be treated as opaque, because its definition may change |
41 | /// without adhering to semantic versioning and depends on what the tool bindgen is able to generate. |
42 | /// |
43 | /// Converting from a Rust wrapper to a wrapped value may lose the automatic ability to free associated memory. |
44 | pub unsafe trait ValueWrapper<N> { |
45 | fn wrap(native: N) -> Self; |
46 | fn unwrap(self) -> N; |
47 | fn inner(&self) -> &N; |
48 | fn inner_mut(&mut self) -> &mut N; |
49 | } |
50 | |
51 | /// A trait that supports the conversion from a C/C++ value into its Rust wrapper and back. |
52 | /// |
53 | /// The wrapped value can be accessed through the functions `inner` and `inner_mut`. |
54 | /// |
55 | /// This trait is implemented for for all types that implement `NativeTransmutable<N>`. |
56 | /// |
57 | /// # Safety |
58 | /// |
59 | /// The native type `N` _should_ be treated as opaque, because its definition may change |
60 | /// without adhering to semantic versioning and depends on what the tool bindgen is able to generate. |
61 | /// |
62 | /// Converting from a Rust wrapper to a wrapped value may lose the automatic ability to free associated memory. |
63 | pub unsafe trait NativeTransmutableWrapper<N> { |
64 | fn wrap(native: N) -> Self; |
65 | fn unwrap(self) -> N; |
66 | fn inner(&self) -> &N; |
67 | fn inner_mut(&mut self) -> &mut N; |
68 | } |
69 | |
70 | /// A trait that supports the conversion from a C/C++ reference into its Rust wrapper and back. |
71 | /// |
72 | /// The wrapped value can be accessed through the functions `inner` and `inner_mut`. |
73 | /// |
74 | /// This trait is implemented for all wrapper types that wrap C/C++ references. |
75 | /// |
76 | /// # Safety |
77 | /// |
78 | /// The native type `N` _should_ be treated as opaque, because its definition may change |
79 | /// without adhering to semantic versioning and depends on what the tool bindgen is able to generate. |
80 | /// |
81 | /// Converting from a Rust wrapper to a wrapped value may lose the automatic ability to free associated memory. |
82 | pub unsafe trait RefWrapper<N> { |
83 | fn wrap_ref(native: &N) -> &Self; |
84 | fn wrap_mut(native: &mut N) -> &mut Self; |
85 | fn inner(&self) -> &N; |
86 | fn inner_mut(&mut self) -> &mut N; |
87 | } |
88 | |
89 | // |
90 | // Handle<N> |
91 | // |
92 | |
93 | unsafe impl<N> ValueWrapper<N> for Handle<N> |
94 | where |
95 | N: NativeDrop, |
96 | { |
97 | fn wrap(native: N) -> Self |
98 | where |
99 | N: NativeDrop, |
100 | { |
101 | Self::from_native_c(native) |
102 | } |
103 | |
104 | fn unwrap(self) -> N { |
105 | self.into_native() |
106 | } |
107 | |
108 | fn inner(&self) -> &N { |
109 | self.native() |
110 | } |
111 | |
112 | fn inner_mut(&mut self) -> &mut N { |
113 | self.native_mut() |
114 | } |
115 | } |
116 | |
117 | unsafe impl<N> RefWrapper<N> for Handle<N> |
118 | where |
119 | N: NativeDrop, |
120 | { |
121 | fn wrap_ref(native: &N) -> &Self { |
122 | Self::from_native_ref(native) |
123 | } |
124 | |
125 | fn wrap_mut(native: &mut N) -> &mut Self { |
126 | Self::from_native_ref_mut(native) |
127 | } |
128 | |
129 | fn inner(&self) -> &N { |
130 | self.native() |
131 | } |
132 | |
133 | fn inner_mut(&mut self) -> &mut N { |
134 | self.native_mut() |
135 | } |
136 | } |
137 | |
138 | // |
139 | // RefHandle<N> |
140 | // |
141 | |
142 | unsafe impl<N> PointerWrapper<N> for RefHandle<N> |
143 | where |
144 | N: NativeDrop, |
145 | { |
146 | fn wrap(ptr: *mut N) -> Option<Self> { |
147 | Self::from_ptr(ptr) |
148 | } |
149 | |
150 | fn unwrap(self) -> *mut N { |
151 | self.into_ptr() |
152 | } |
153 | |
154 | fn inner(&self) -> &N { |
155 | self.native() |
156 | } |
157 | |
158 | fn inner_mut(&mut self) -> &mut N { |
159 | self.native_mut() |
160 | } |
161 | } |
162 | |
163 | // |
164 | // RCHandle<N> |
165 | // |
166 | |
167 | unsafe impl<N> PointerWrapper<N> for RCHandle<N> |
168 | where |
169 | N: NativeRefCounted, |
170 | { |
171 | fn wrap(ptr: *mut N) -> Option<Self> { |
172 | Self::from_ptr(ptr) |
173 | } |
174 | |
175 | fn unwrap(self) -> *mut N { |
176 | self.into_ptr() |
177 | } |
178 | |
179 | fn inner(&self) -> &N { |
180 | self.native() |
181 | } |
182 | |
183 | fn inner_mut(&mut self) -> &mut N { |
184 | self.native_mut() |
185 | } |
186 | } |
187 | |
188 | // |
189 | // NativeTransmutable<N> |
190 | // |
191 | |
192 | unsafe impl<N, T> NativeTransmutableWrapper<N> for T |
193 | where |
194 | N: Sized, |
195 | T: Sized, |
196 | T: NativeTransmutable<N>, |
197 | { |
198 | fn wrap(native: N) -> Self { |
199 | Self::from_native_c(nt:native) |
200 | } |
201 | |
202 | fn unwrap(self) -> N { |
203 | Self::into_native(self) |
204 | } |
205 | |
206 | fn inner(&self) -> &N { |
207 | self.native() |
208 | } |
209 | |
210 | fn inner_mut(&mut self) -> &mut N { |
211 | self.native_mut() |
212 | } |
213 | } |
214 | |