| 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 | |