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.
5use 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.
17pub unsafe trait PointerWrapper<N>
18where
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.
44pub 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.
63pub 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.
82pub 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
93unsafe impl<N> ValueWrapper<N> for Handle<N>
94where
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
117unsafe impl<N> RefWrapper<N> for Handle<N>
118where
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
142unsafe impl<N> PointerWrapper<N> for RefHandle<N>
143where
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
167unsafe impl<N> PointerWrapper<N> for RCHandle<N>
168where
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
192unsafe impl<N, T> NativeTransmutableWrapper<N> for T
193where
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