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