skia_safe/
wrapper.rs

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