skia_safe/
prelude.rs

1#![allow(dead_code)]
2use std::{
3    cell::UnsafeCell,
4    fmt::Debug,
5    hash::{Hash, Hasher},
6    marker::PhantomData,
7    mem,
8    ops::{Deref, DerefMut, Index, IndexMut},
9    ptr, slice,
10};
11
12use skia_bindings::{
13    sk_sp, C_SkRefCntBase_ref, C_SkRefCntBase_unique, C_SkRefCntBase_unref, SkRefCnt, SkRefCntBase,
14};
15
16/// Convert any reference into any other.
17pub(crate) unsafe fn transmute_ref<FromT, ToT>(from: &FromT) -> &ToT {
18    assert_layout_compatible::<FromT, ToT>();
19    &*(from as *const FromT as *const ToT)
20}
21
22pub(crate) unsafe fn transmute_ref_mut<FromT, ToT>(from: &mut FromT) -> &mut ToT {
23    assert_layout_compatible::<FromT, ToT>();
24    &mut *(from as *mut FromT as *mut ToT)
25}
26
27pub(crate) trait IntoNonNull {
28    type Target;
29    fn into_non_null(self) -> Option<ptr::NonNull<Self::Target>>;
30}
31
32impl<T> IntoNonNull for *const T {
33    type Target = T;
34
35    fn into_non_null(self) -> Option<ptr::NonNull<Self::Target>> {
36        ptr::NonNull::new(self as *mut T)
37    }
38}
39
40impl<T> IntoNonNull for *mut T {
41    type Target = T;
42
43    fn into_non_null(self) -> Option<ptr::NonNull<Self::Target>> {
44        ptr::NonNull::new(self)
45    }
46}
47
48#[cfg(test)]
49pub(crate) trait RefCount {
50    fn ref_cnt(&self) -> usize;
51}
52
53#[cfg(test)]
54impl RefCount for SkRefCntBase {
55    // the problem here is that the binding generator represents std::atomic as an u8 (we
56    // are lucky that the C alignment rules make space for an i32), so to get the ref
57    // counter, we need to get the u8 pointer to fRefCnt and interpret it as an i32 pointer.
58    #[allow(clippy::cast_ptr_alignment)]
59    fn ref_cnt(&self) -> usize {
60        unsafe {
61            let ptr: *const i32 = &self.fRefCnt as *const _ as *const i32;
62            (*ptr).try_into().unwrap()
63        }
64    }
65}
66
67impl NativeBase<SkRefCntBase> for SkRefCnt {}
68
69#[cfg(test)]
70impl RefCount for SkRefCnt {
71    fn ref_cnt(&self) -> usize {
72        self.base().ref_cnt()
73    }
74}
75
76#[cfg(test)]
77impl RefCount for skia_bindings::SkNVRefCnt {
78    #[allow(clippy::cast_ptr_alignment)]
79    fn ref_cnt(&self) -> usize {
80        unsafe {
81            let ptr: *const i32 = &self.fRefCnt as *const _ as *const i32;
82            (*ptr).try_into().unwrap()
83        }
84    }
85}
86
87pub trait NativeRefCounted: Sized {
88    fn _ref(&self);
89    fn _unref(&self);
90    fn unique(&self) -> bool;
91    fn _ref_cnt(&self) -> usize {
92        unimplemented!();
93    }
94}
95
96impl NativeRefCounted for SkRefCntBase {
97    fn _ref(&self) {
98        unsafe { C_SkRefCntBase_ref(self) }
99    }
100
101    fn _unref(&self) {
102        unsafe { C_SkRefCntBase_unref(self) }
103    }
104
105    fn unique(&self) -> bool {
106        unsafe { C_SkRefCntBase_unique(self) }
107    }
108
109    #[allow(clippy::cast_ptr_alignment)]
110    fn _ref_cnt(&self) -> usize {
111        unsafe {
112            let ptr: *const i32 = &self.fRefCnt as *const _ as *const i32;
113            (*ptr).try_into().unwrap()
114        }
115    }
116}
117
118/// Implements NativeRefCounted by just providing a reference to the base class
119/// that implements a RefCount.
120/// TODO: use NativeBase
121pub trait NativeRefCountedBase {
122    type Base: NativeRefCounted;
123
124    /// Returns the ref counter base class of the ref counted type.
125    ///
126    /// Default implementation assumes that the base class ptr is the same as the
127    /// ptr to self.
128    fn ref_counted_base(&self) -> &Self::Base {
129        unsafe { &*(self as *const _ as *const Self::Base) }
130    }
131}
132
133impl<Native, Base: NativeRefCounted> NativeRefCounted for Native
134where
135    Native: NativeRefCountedBase<Base = Base>,
136{
137    fn _ref(&self) {
138        self.ref_counted_base()._ref();
139    }
140
141    fn _unref(&self) {
142        self.ref_counted_base()._unref();
143    }
144
145    fn unique(&self) -> bool {
146        self.ref_counted_base().unique()
147    }
148
149    fn _ref_cnt(&self) -> usize {
150        self.ref_counted_base()._ref_cnt()
151    }
152}
153
154/// Trait that enables access to a native representation of a wrapper type.
155pub trait NativeAccess {
156    type Native;
157    /// Provides shared access to the native type of the wrapper.
158    fn native(&self) -> &Self::Native;
159
160    /// Provides exclusive access to the native type of the wrapper.
161    fn native_mut(&mut self) -> &mut Self::Native;
162
163    // Returns a ptr to the native mutable value.
164    unsafe fn native_mut_force(&self) -> *mut Self::Native {
165        self.native() as *const Self::Native as *mut Self::Native
166    }
167}
168
169/// Implements Drop for native types we can not implement Drop for.
170pub trait NativeDrop {
171    fn drop(&mut self);
172}
173
174/// Clone for bindings types we can not implement Clone for.
175pub trait NativeClone {
176    fn clone(&self) -> Self;
177}
178
179/// Even though some types may have value semantics, equality
180/// comparison may need to be customized.
181pub trait NativePartialEq {
182    fn eq(&self, rhs: &Self) -> bool;
183}
184
185/// Implements Hash for the native type so that the wrapper type
186/// can derive it from.
187pub trait NativeHash {
188    fn hash<H: Hasher>(&self, state: &mut H);
189}
190
191/// Wraps a native type that can be represented in Rust memory.
192///
193/// This type requires an implementation of the `NativeDrop` trait.
194#[repr(transparent)]
195pub struct Handle<N: NativeDrop>(
196    // UnsafeCell is used for disabling niche optimization, because we don't care about the proper
197    // representations of bindgen types as long the size and alighment matches.
198    UnsafeCell<N>,
199    // `*const` is needed to prevent automatic Send implementation, which happens when the
200    // native type is Send.
201    PhantomData<*const ()>,
202);
203
204impl<N: NativeDrop> AsRef<Handle<N>> for Handle<N> {
205    fn as_ref(&self) -> &Self {
206        self
207    }
208}
209
210impl<N: NativeDrop> Handle<N> {
211    /// Wrap a native instance into a handle.
212    #[must_use]
213    pub(crate) fn from_native_c(n: N) -> Self {
214        Handle(n.into(), PhantomData)
215    }
216
217    /// Create a reference to the Rust wrapper from a reference to the native type.
218    #[must_use]
219    pub(crate) fn from_native_ref(n: &N) -> &Self {
220        unsafe { transmute_ref(n) }
221    }
222
223    /// Create a mutable reference to the Rust wrapper from a reference to the native type.
224    #[must_use]
225    pub(crate) fn from_native_ref_mut(n: &mut N) -> &mut Self {
226        unsafe { transmute_ref_mut(n) }
227    }
228
229    /// Converts a pointer to a native value into a pointer to the Rust value.
230    #[must_use]
231    pub(crate) fn from_native_ptr(np: *const N) -> *const Self {
232        np as _
233    }
234
235    /// Converts a pointer to a mutable native value into a pointer to the mutable Rust value.
236    #[allow(unused)]
237    #[must_use]
238    pub(crate) fn from_native_ptr_mut(np: *mut N) -> *mut Self {
239        np as _
240    }
241
242    /// Constructs a C++ object in place by calling a
243    /// function that expects a pointer that points to
244    /// uninitialized memory of the native type.
245    #[must_use]
246    pub(crate) fn construct(construct: impl FnOnce(*mut N)) -> Self {
247        Self::try_construct(|i| {
248            construct(i);
249            true
250        })
251        .unwrap()
252    }
253
254    pub(crate) fn try_construct(construct: impl FnOnce(*mut N) -> bool) -> Option<Self> {
255        self::try_construct(construct).map(|n| Self::from_native_c(n.into_inner()))
256    }
257
258    /// Replaces the native instance with the one from this Handle, and returns the replaced one
259    /// wrapped in a Rust Handle without dropping either one.
260    #[must_use]
261    pub(crate) fn replace_native(mut self, native: &mut N) -> Self {
262        mem::swap(self.0.get_mut(), native);
263        self
264    }
265
266    /// Consumes the wrapper and returns the native type.
267    #[must_use]
268    pub(crate) fn into_native(mut self) -> N {
269        let r = mem::replace(&mut self.0, unsafe { mem::zeroed() });
270        mem::forget(self);
271        r.into_inner()
272    }
273}
274
275pub(crate) trait ReplaceWith<Other> {
276    fn replace_with(&mut self, other: Other) -> Other;
277}
278
279impl<N: NativeDrop> ReplaceWith<Handle<N>> for N {
280    fn replace_with(&mut self, other: Handle<N>) -> Handle<N> {
281        other.replace_native(self)
282    }
283}
284
285/// Constructs a C++ object in place by calling a lambda that is meant to initialize
286/// the pointer to the Rust memory provided as a pointer.
287#[must_use]
288pub(crate) fn construct<N>(construct: impl FnOnce(*mut N)) -> N {
289    try_construct(|i| {
290        construct(i);
291        true
292    })
293    .unwrap()
294    .into_inner()
295}
296
297#[must_use]
298pub(crate) fn try_construct<N>(construct: impl FnOnce(*mut N) -> bool) -> Option<UnsafeCell<N>> {
299    let mut instance = mem::MaybeUninit::uninit();
300    construct(instance.as_mut_ptr()).then_some(unsafe { instance.assume_init() }.into())
301}
302
303impl<N: NativeDrop> Drop for Handle<N> {
304    fn drop(&mut self) {
305        self.0.get_mut().drop()
306    }
307}
308
309impl<N: NativeDrop> NativeAccess for Handle<N> {
310    type Native = N;
311
312    fn native(&self) -> &N {
313        unsafe { &*(self.0.get()) }
314    }
315
316    fn native_mut(&mut self) -> &mut N {
317        self.0.get_mut()
318    }
319}
320
321impl<N: NativeDrop + NativeClone> Clone for Handle<N> {
322    fn clone(&self) -> Self {
323        Self::from_native_c(self.native().clone())
324    }
325}
326
327impl<N: NativeDrop + NativePartialEq> PartialEq for Handle<N> {
328    fn eq(&self, rhs: &Self) -> bool {
329        self.native().eq(rhs.native())
330    }
331}
332
333impl<N: NativeDrop + NativeHash> Hash for Handle<N> {
334    fn hash<H: Hasher>(&self, state: &mut H) {
335        self.native().hash(state);
336    }
337}
338
339pub(crate) trait NativeSliceAccess<N: NativeDrop> {
340    fn native(&self) -> &[N];
341    fn native_mut(&mut self) -> &mut [N];
342}
343
344impl<N: NativeDrop> NativeSliceAccess<N> for [Handle<N>] {
345    fn native(&self) -> &[N] {
346        let ptr = self.first().native_ptr_or_null();
347        unsafe { slice::from_raw_parts(ptr, self.len()) }
348    }
349
350    fn native_mut(&mut self) -> &mut [N] {
351        let ptr = self.first_mut().native_ptr_or_null_mut();
352        unsafe { slice::from_raw_parts_mut(ptr, self.len()) }
353    }
354}
355
356/// A trait that supports retrieving a pointer from an Option<Handle<Native>>.
357/// Returns a null pointer if the Option is None.
358pub(crate) trait NativePointerOrNull {
359    type Native;
360
361    fn native_ptr_or_null(&self) -> *const Self::Native;
362    unsafe fn native_ptr_or_null_mut_force(&self) -> *mut Self::Native;
363}
364
365pub(crate) trait NativePointerOrNullMut {
366    type Native;
367
368    fn native_ptr_or_null_mut(&mut self) -> *mut Self::Native;
369}
370
371impl<H, N> NativePointerOrNull for Option<&H>
372where
373    H: NativeAccess<Native = N>,
374{
375    type Native = N;
376
377    fn native_ptr_or_null(&self) -> *const N {
378        match self {
379            Some(handle) => handle.native(),
380            None => ptr::null(),
381        }
382    }
383
384    unsafe fn native_ptr_or_null_mut_force(&self) -> *mut N {
385        match self {
386            Some(handle) => handle.native_mut_force(),
387            None => ptr::null_mut(),
388        }
389    }
390}
391
392impl<H, N> NativePointerOrNullMut for Option<&mut H>
393where
394    H: NativeAccess<Native = N>,
395{
396    type Native = N;
397
398    fn native_ptr_or_null_mut(&mut self) -> *mut N {
399        match self {
400            Some(handle) => handle.native_mut(),
401            None => ptr::null_mut(),
402        }
403    }
404}
405
406pub(crate) trait NativePointerOrNullMut2<N> {
407    fn native_ptr_or_null_mut(&mut self) -> *mut N;
408}
409
410pub(crate) trait NativePointerOrNull2<N> {
411    fn native_ptr_or_null(&self) -> *const N;
412}
413
414impl<H, N> NativePointerOrNull2<N> for Option<&H>
415where
416    H: NativeTransmutable<N>,
417{
418    fn native_ptr_or_null(&self) -> *const N {
419        match self {
420            Some(handle) => handle.native(),
421            None => ptr::null(),
422        }
423    }
424}
425
426impl<H, N> NativePointerOrNullMut2<N> for Option<&mut H>
427where
428    H: NativeTransmutable<N>,
429{
430    fn native_ptr_or_null_mut(&mut self) -> *mut N {
431        match self {
432            Some(handle) => handle.native_mut(),
433            None => ptr::null_mut(),
434        }
435    }
436}
437
438/// A wrapper type that represents a native type with a pointer to
439/// the native object.
440#[repr(transparent)]
441pub struct RefHandle<N: NativeDrop>(ptr::NonNull<N>);
442
443impl<N: NativeDrop> Drop for RefHandle<N> {
444    fn drop(&mut self) {
445        self.native_mut().drop()
446    }
447}
448
449impl<N: NativeDrop + NativePartialEq> PartialEq for RefHandle<N> {
450    fn eq(&self, rhs: &Self) -> bool {
451        self.native().eq(rhs.native())
452    }
453}
454
455impl<N: NativeDrop> NativeAccess for RefHandle<N> {
456    type Native = N;
457
458    fn native(&self) -> &N {
459        unsafe { self.0.as_ref() }
460    }
461    fn native_mut(&mut self) -> &mut N {
462        unsafe { self.0.as_mut() }
463    }
464}
465
466impl<N: NativeDrop> RefHandle<N> {
467    /// Creates a RefHandle from a native pointer.
468    ///
469    /// From this time on, the handle owns the object that the pointer points
470    /// to and will call its NativeDrop implementation if it goes out of scope.
471    pub(crate) fn from_ptr(ptr: *mut N) -> Option<Self> {
472        ptr::NonNull::new(ptr).map(Self)
473    }
474
475    pub(crate) fn into_ptr(self) -> *mut N {
476        let p = self.0.as_ptr();
477        mem::forget(self);
478        p
479    }
480}
481
482/// A wrapper type represented by a reference counted pointer
483/// to the native type.
484#[repr(transparent)]
485pub struct RCHandle<Native: NativeRefCounted>(ptr::NonNull<Native>);
486
487/// A reference counted handle is cheap to clone, so we do support a conversion
488/// from a reference to a ref counter to an owned handle.
489impl<N: NativeRefCounted> From<&RCHandle<N>> for RCHandle<N> {
490    fn from(rch: &RCHandle<N>) -> Self {
491        rch.clone()
492    }
493}
494
495impl<N: NativeRefCounted> AsRef<RCHandle<N>> for RCHandle<N> {
496    fn as_ref(&self) -> &Self {
497        self
498    }
499}
500
501impl<N: NativeRefCounted> RCHandle<N> {
502    /// Creates an reference counted handle from a native pointer.
503    ///
504    /// Takes ownership of the object the pointer points to, does not increase the reference count.
505    ///
506    /// Returns `None` if the pointer is `null`.
507    #[inline]
508    pub(crate) fn from_ptr(ptr: *mut N) -> Option<Self> {
509        ptr::NonNull::new(ptr).map(Self)
510    }
511
512    /// Creates an reference counted handle from a pointer.
513    ///
514    /// Returns `None` if the pointer is `null`.
515    ///
516    /// Shares ownership with the object referenced to by the pointer, therefore increases the
517    /// reference count.
518    #[inline]
519    pub(crate) fn from_unshared_ptr(ptr: *mut N) -> Option<Self> {
520        ptr::NonNull::new(ptr).map(|ptr| {
521            unsafe { ptr.as_ref()._ref() };
522            Self(ptr)
523        })
524    }
525
526    /// Create a reference to the Rust wrapper from a reference to a pointer that points
527    /// to the native type.
528    pub(crate) fn from_unshared_ptr_ref(n: &*mut N) -> &Option<Self> {
529        unsafe { transmute_ref(n) }
530    }
531
532    /// Create a reference to a all non-null sk_sp<N> slice.
533    pub(crate) fn from_non_null_sp_slice(sp_slice: &[sk_sp<N>]) -> &[Self] {
534        assert_layout_compatible::<sk_sp<N>, Self>();
535        assert!(sp_slice.iter().all(|v| !v.fPtr.is_null()));
536        unsafe { mem::transmute(sp_slice) }
537    }
538
539    /// Returns the pointer to the handle.
540    #[allow(unused)]
541    pub(crate) fn as_ptr(&self) -> &ptr::NonNull<N> {
542        &self.0
543    }
544}
545
546#[cfg(test)]
547mod rc_handle_tests {
548    use std::ptr;
549
550    use skia_bindings::{SkFontMgr, SkTypeface};
551
552    use crate::{prelude::NativeAccess, FontMgr, Typeface};
553
554    #[test]
555    fn rc_native_ref_null() {
556        let f: *mut SkTypeface = ptr::null_mut();
557        let r = Typeface::from_unshared_ptr(f);
558        assert!(r.is_none())
559    }
560
561    #[test]
562    fn rc_native_ref_non_null() {
563        let mut font_mgr = FontMgr::new();
564        let f: *mut SkFontMgr = font_mgr.native_mut();
565        let r = FontMgr::from_unshared_ptr(f);
566        assert!(r.is_some())
567    }
568}
569
570impl<N: NativeRefCounted> NativeAccess for RCHandle<N> {
571    type Native = N;
572
573    /// Returns a reference to the native representation.
574    fn native(&self) -> &N {
575        unsafe { self.0.as_ref() }
576    }
577
578    /// Returns a mutable reference to the native representation.
579    fn native_mut(&mut self) -> &mut N {
580        unsafe { self.0.as_mut() }
581    }
582}
583
584impl<N: NativeRefCounted> Clone for RCHandle<N> {
585    fn clone(&self) -> Self {
586        // Support shared mutability when a ref-counted handle is cloned.
587        let ptr = self.0;
588        unsafe { ptr.as_ref()._ref() };
589        Self(ptr)
590    }
591}
592
593impl<N: NativeRefCounted> Drop for RCHandle<N> {
594    #[inline]
595    fn drop(&mut self) {
596        unsafe { self.0.as_ref()._unref() };
597    }
598}
599
600impl<N: NativeRefCounted + NativePartialEq> PartialEq for RCHandle<N> {
601    fn eq(&self, rhs: &Self) -> bool {
602        self.native().eq(rhs.native())
603    }
604}
605
606/// A trait that consumes self and converts it to a ptr to the native type.
607pub(crate) trait IntoPtr<N> {
608    fn into_ptr(self) -> *mut N;
609}
610
611impl<N: NativeRefCounted> IntoPtr<N> for RCHandle<N> {
612    fn into_ptr(self) -> *mut N {
613        let ptr = self.0.as_ptr();
614        mem::forget(self);
615        ptr
616    }
617}
618
619/// A trait that consumes self and converts it to a ptr to the native type or null.
620pub(crate) trait IntoPtrOrNull {
621    type Native;
622    fn into_ptr_or_null(self) -> *mut Self::Native;
623}
624
625impl<N: NativeRefCounted> IntoPtrOrNull for Option<RCHandle<N>> {
626    type Native = N;
627    fn into_ptr_or_null(self) -> *mut N {
628        self.map(|rc| rc.into_ptr()).unwrap_or(ptr::null_mut())
629    }
630}
631
632/// Tag the type to automatically implement get() functions for
633/// all Index implementations.
634pub trait IndexGet {}
635
636/// Tag the type to automatically implement get() and set() functions
637/// for all Index & IndexMut implementation for that type.
638pub trait IndexSet {}
639
640pub trait IndexGetter<I, O: Copy> {
641    // TODO: Not sure why clippy 1.78-beta.1 complains about this one.
642    #[allow(unused)]
643    fn get(&self, index: I) -> O;
644}
645
646impl<T, I, O: Copy> IndexGetter<I, O> for T
647where
648    T: Index<I, Output = O> + IndexGet,
649{
650    fn get(&self, index: I) -> O {
651        self[index]
652    }
653}
654
655pub trait IndexSetter<I, O: Copy> {
656    fn set(&mut self, index: I, value: O) -> &mut Self;
657}
658
659impl<T, I, O: Copy> IndexSetter<I, O> for T
660where
661    T: IndexMut<I, Output = O> + IndexSet,
662{
663    fn set(&mut self, index: I, value: O) -> &mut Self {
664        self[index] = value;
665        self
666    }
667}
668
669/// Trait to mark a native type that can be treated a Rust type _inplace_ with the same size and
670/// field layout.
671pub trait NativeTransmutable<NT: Sized>: Sized
672where
673    Self: Sized,
674{
675    /// Provides access to the native value through a
676    /// transmuted reference to the Rust value.
677    fn native(&self) -> &NT {
678        unsafe { transmute_ref(self) }
679    }
680
681    /// Provides mutable access to the native value through a transmuted reference to the Rust
682    /// value.
683    fn native_mut(&mut self) -> &mut NT {
684        unsafe { transmute_ref_mut(self) }
685    }
686
687    /// Copies the native value to an equivalent Rust value.
688    ///
689    /// The `_c` suffix is to remind callers that values that requires C++ ABI features can't be
690    /// used here.
691    fn from_native_c(nt: NT) -> Self {
692        let r = unsafe { mem::transmute_copy::<NT, Self>(&nt) };
693        // don't drop, the Rust type takes over.
694        mem::forget(nt);
695        r
696    }
697
698    /// Copies the rust type to an equivalent instance of the native type.
699    fn into_native(self) -> NT {
700        let r = unsafe { mem::transmute_copy::<Self, NT>(&self) };
701        // don't drop, the native type takes over.
702        mem::forget(self);
703        r
704    }
705
706    /// Returns a reference to the Rust value by transmuting a reference to the native value.
707    fn from_native_ref(nt: &NT) -> &Self {
708        unsafe { transmute_ref(nt) }
709    }
710
711    /// Returns a reference to the Rust array reference by transmuting a reference to the native
712    /// array.
713    fn from_native_array_ref<const N: usize>(nt: &[NT; N]) -> &[Self; N] {
714        unsafe { transmute_ref(nt) }
715    }
716
717    /// Returns a reference to the Rust value through a transmuted reference to the native mutable
718    /// value.
719    fn from_native_ref_mut(nt: &mut NT) -> &mut Self {
720        unsafe { transmute_ref_mut(nt) }
721    }
722
723    /// Converts a pointer to a native value into a pointer to the Rust value.
724    fn from_native_ptr(np: *const NT) -> *const Self {
725        np as _
726    }
727
728    /// Converts a pointer to a mutable native value into a pointer to the mutable Rust value.
729    fn from_native_ptr_mut(np: *mut NT) -> *mut Self {
730        np as _
731    }
732
733    fn construct(construct: impl FnOnce(*mut NT)) -> Self {
734        Self::try_construct(|i| {
735            construct(i);
736            true
737        })
738        .unwrap()
739    }
740
741    fn try_construct(construct: impl FnOnce(*mut NT) -> bool) -> Option<Self> {
742        self::try_construct(construct).map(|n| Self::from_native_c(n.into_inner()))
743    }
744}
745
746/// Tests if T1 and T2 do have the same size and alignment.
747pub(crate) const fn assert_layout_compatible<T1, T2>() {
748    assert!(
749        mem::size_of::<T1>() == mem::size_of::<T2>(),
750        "Type layout verification failed: Size mismatch"
751    );
752    assert!(
753        mem::align_of::<T1>() == mem::align_of::<T2>(),
754        "Type layout verficiation failed: Alignment mismatch"
755    );
756}
757
758pub(crate) trait NativeTransmutableSliceAccess<NT: Sized> {
759    fn native(&self) -> &[NT];
760    fn native_mut(&mut self) -> &mut [NT];
761}
762
763impl<NT, ElementT> NativeTransmutableSliceAccess<NT> for [ElementT]
764where
765    ElementT: NativeTransmutable<NT>,
766{
767    fn native(&self) -> &[NT] {
768        unsafe { &*(self as *const [ElementT] as *const [NT]) }
769    }
770
771    fn native_mut(&mut self) -> &mut [NT] {
772        unsafe { &mut *(self as *mut [ElementT] as *mut [NT]) }
773    }
774}
775
776impl<NT, RustT> NativeTransmutable<Option<NT>> for Option<RustT> where RustT: NativeTransmutable<NT> {}
777
778impl<NT, RustT> NativeTransmutable<Option<&[NT]>> for Option<&[RustT]> where
779    RustT: NativeTransmutable<NT>
780{
781}
782
783pub(crate) trait NativeTransmutableOptionSliceAccessMut<NT: Sized> {
784    fn native_mut(&mut self) -> &mut Option<&mut [NT]>;
785}
786
787impl<NT, RustT> NativeTransmutableOptionSliceAccessMut<NT> for Option<&mut [RustT]>
788where
789    RustT: NativeTransmutable<NT>,
790{
791    fn native_mut(&mut self) -> &mut Option<&mut [NT]> {
792        unsafe { transmute_ref_mut(self) }
793    }
794}
795
796//
797// Convenience functions to access Option<&[]> as optional ptr (opt_ptr)
798// that may be null.
799//
800
801pub(crate) trait AsPointerOrNull<PointerT> {
802    fn as_ptr_or_null(&self) -> *const PointerT;
803}
804
805pub(crate) trait AsPointerOrNullMut<PointerT>: AsPointerOrNull<PointerT> {
806    fn as_ptr_or_null_mut(&mut self) -> *mut PointerT;
807}
808
809impl<E> AsPointerOrNull<E> for Option<E> {
810    fn as_ptr_or_null(&self) -> *const E {
811        match self {
812            Some(e) => e,
813            None => ptr::null(),
814        }
815    }
816}
817
818impl<E> AsPointerOrNullMut<E> for Option<E> {
819    fn as_ptr_or_null_mut(&mut self) -> *mut E {
820        match self {
821            Some(e) => e,
822            None => ptr::null_mut(),
823        }
824    }
825}
826
827impl<E> AsPointerOrNull<E> for Option<&[E]> {
828    fn as_ptr_or_null(&self) -> *const E {
829        match self {
830            Some(slice) => slice.as_ptr(),
831            None => ptr::null(),
832        }
833    }
834}
835
836impl<E> AsPointerOrNull<E> for Option<&mut [E]> {
837    fn as_ptr_or_null(&self) -> *const E {
838        match self {
839            Some(slice) => slice.as_ptr(),
840            None => ptr::null(),
841        }
842    }
843}
844
845impl<E> AsPointerOrNullMut<E> for Option<&mut [E]> {
846    fn as_ptr_or_null_mut(&mut self) -> *mut E {
847        match self {
848            Some(slice) => slice.as_mut_ptr(),
849            None => ptr::null_mut(),
850        }
851    }
852}
853
854impl<E> AsPointerOrNull<E> for Option<&Vec<E>> {
855    fn as_ptr_or_null(&self) -> *const E {
856        match self {
857            Some(v) => v.as_ptr(),
858            None => ptr::null(),
859        }
860    }
861}
862
863impl<E> AsPointerOrNull<E> for Option<Vec<E>> {
864    fn as_ptr_or_null(&self) -> *const E {
865        match self {
866            Some(v) => v.as_ptr(),
867            None => ptr::null(),
868        }
869    }
870}
871
872impl<E> AsPointerOrNullMut<E> for Option<Vec<E>> {
873    fn as_ptr_or_null_mut(&mut self) -> *mut E {
874        match self {
875            Some(v) => v.as_mut_ptr(),
876            None => ptr::null_mut(),
877        }
878    }
879}
880
881// Wraps a handle so that the Rust's borrow checker assumes it represents
882// something that borrows something else.
883#[repr(transparent)]
884pub struct Borrows<'a, H>(H, PhantomData<&'a ()>);
885
886impl<H> Deref for Borrows<'_, H> {
887    type Target = H;
888    fn deref(&self) -> &Self::Target {
889        &self.0
890    }
891}
892
893// TODO: this is most likely unsafe because someone could replace the
894// value the reference is pointing to.
895impl<H> DerefMut for Borrows<'_, H> {
896    fn deref_mut(&mut self) -> &mut Self::Target {
897        &mut self.0
898    }
899}
900
901impl<H> Borrows<'_, H> {
902    /// Notify that the borrowed dependency is not referred to anymore and return the handle.
903    /// # Safety
904    /// The borrowed dependency must be removed before calling `release()`.
905    pub unsafe fn release(self) -> H {
906        self.0
907    }
908}
909
910pub(crate) trait BorrowsFrom: Sized {
911    fn borrows<D: ?Sized>(self, _dep: &D) -> Borrows<Self>;
912}
913
914impl<T: Sized> BorrowsFrom for T {
915    fn borrows<D: ?Sized>(self, _dep: &D) -> Borrows<Self> {
916        Borrows(self, PhantomData)
917    }
918}
919
920impl<H> Borrows<'_, H> {
921    pub(crate) unsafe fn unchecked_new(h: H) -> Self {
922        Self(h, PhantomData)
923    }
924}
925
926/// Declares a base class for a native type.
927pub trait NativeBase<Base> {
928    fn base(&self) -> &Base {
929        unsafe { &*(self as *const Self as *const Base) }
930    }
931
932    fn base_mut(&mut self) -> &mut Base {
933        unsafe { &mut *(self as *mut Self as *mut Base) }
934    }
935}
936
937pub struct Sendable<H: ConditionallySend>(H);
938unsafe impl<H: ConditionallySend> Send for Sendable<H> {}
939
940impl<H: ConditionallySend> Sendable<H> {
941    #[deprecated(note = "Use Sendable::into_inner() instead")]
942    pub fn unwrap(self) -> H {
943        self.0
944    }
945
946    pub fn into_inner(self) -> H {
947        self.0
948    }
949}
950
951impl<H> Debug for Sendable<H>
952where
953    H: Debug + ConditionallySend,
954{
955    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
956        f.debug_tuple("Sendable").field(&self.0).finish()
957    }
958}
959
960pub trait ConditionallySend: Sized {
961    /// Returns `true` if the handle can be sent to another thread.
962    fn can_send(&self) -> bool;
963    /// Wrap the handle in a type that can be sent to another thread and unwrapped there.
964    ///
965    /// Guaranteed to succeed of can_send() returns `true`.
966    fn wrap_send(self) -> Result<Sendable<Self>, Self>;
967}
968
969/// `RCHandle<H>` is conditionally Send and can be sent to
970/// another thread when its reference count is 1.
971impl<H: NativeRefCountedBase> ConditionallySend for RCHandle<H> {
972    fn can_send(&self) -> bool {
973        self.native().unique()
974    }
975
976    fn wrap_send(self) -> Result<Sendable<Self>, Self> {
977        if self.can_send() {
978            Ok(Sendable(self))
979        } else {
980            Err(self)
981        }
982    }
983}
984
985/// Functions that are (supposedly) _safer_ variants of the ones Rust provides.
986pub(crate) mod safer {
987    use core::slice;
988    use std::ptr;
989
990    /// Invokes [slice::from_raw_parts] with the `ptr` only when `len` != 0, otherwise passes
991    /// `ptr::NonNull::dangling()` as recommended.
992    ///
993    /// Panics if `len` != 0 and `ptr` is `null`.
994    pub unsafe fn from_raw_parts<'a, T>(ptr: *const T, len: usize) -> &'a [T] {
995        let ptr = if len == 0 {
996            ptr::NonNull::dangling().as_ptr()
997        } else {
998            assert!(!ptr.is_null());
999            ptr
1000        };
1001        slice::from_raw_parts(ptr, len)
1002    }
1003
1004    /// Invokes [slice::from_raw_parts_mut] with the `ptr` only if `len` != 0, otherwise passes
1005    /// `ptr::NonNull::dangling()` as recommended.
1006    ///
1007    /// Panics if `len` != 0 and `ptr` is `null`.
1008    pub unsafe fn from_raw_parts_mut<'a, T>(ptr: *mut T, len: usize) -> &'a mut [T] {
1009        let ptr = if len == 0 {
1010            ptr::NonNull::dangling().as_ptr() as *mut _
1011        } else {
1012            assert!(!ptr.is_null());
1013            ptr
1014        };
1015        slice::from_raw_parts_mut(ptr, len)
1016    }
1017}