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 alignment 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(|| 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    #[inline]
513    pub(crate) fn from_ptr_const(ptr: *const N) -> Option<Self> {
514        ptr::NonNull::new(ptr as *mut N).map(Self)
515    }
516
517    /// Creates an reference counted handle from a pointer.
518    ///
519    /// Returns `None` if the pointer is `null`.
520    ///
521    /// Shares ownership with the object referenced to by the pointer, therefore increases the
522    /// reference count.
523    #[inline]
524    pub(crate) fn from_unshared_ptr(ptr: *mut N) -> Option<Self> {
525        ptr::NonNull::new(ptr).map(|ptr| {
526            unsafe { ptr.as_ref()._ref() };
527            Self(ptr)
528        })
529    }
530
531    /// Create a reference to the Rust wrapper from a reference to a pointer that points
532    /// to the native type.
533    pub(crate) fn from_unshared_ptr_ref(n: &*mut N) -> &Option<Self> {
534        unsafe { transmute_ref(n) }
535    }
536
537    /// Create a reference to a all non-null sk_sp<N> slice.
538    pub(crate) fn from_non_null_sp_slice(sp_slice: &[sk_sp<N>]) -> &[Self] {
539        assert_layout_compatible::<sk_sp<N>, Self>();
540        assert!(sp_slice.iter().all(|v| !v.fPtr.is_null()));
541        unsafe { mem::transmute(sp_slice) }
542    }
543
544    /// Returns the pointer to the handle.
545    #[allow(unused)]
546    pub(crate) fn as_ptr(&self) -> &ptr::NonNull<N> {
547        &self.0
548    }
549}
550
551#[cfg(test)]
552mod rc_handle_tests {
553    use std::ptr;
554
555    use skia_bindings::{SkFontMgr, SkTypeface};
556
557    use crate::{prelude::NativeAccess, FontMgr, Typeface};
558
559    #[test]
560    fn rc_native_ref_null() {
561        let f: *mut SkTypeface = ptr::null_mut();
562        let r = Typeface::from_unshared_ptr(f);
563        assert!(r.is_none())
564    }
565
566    #[test]
567    fn rc_native_ref_non_null() {
568        let mut font_mgr = FontMgr::new();
569        let f: *mut SkFontMgr = font_mgr.native_mut();
570        let r = FontMgr::from_unshared_ptr(f);
571        assert!(r.is_some())
572    }
573}
574
575impl<N: NativeRefCounted> NativeAccess for RCHandle<N> {
576    type Native = N;
577
578    /// Returns a reference to the native representation.
579    fn native(&self) -> &N {
580        unsafe { self.0.as_ref() }
581    }
582
583    /// Returns a mutable reference to the native representation.
584    fn native_mut(&mut self) -> &mut N {
585        unsafe { self.0.as_mut() }
586    }
587}
588
589impl<N: NativeRefCounted> Clone for RCHandle<N> {
590    fn clone(&self) -> Self {
591        // Support shared mutability when a ref-counted handle is cloned.
592        let ptr = self.0;
593        unsafe { ptr.as_ref()._ref() };
594        Self(ptr)
595    }
596}
597
598impl<N: NativeRefCounted> Drop for RCHandle<N> {
599    #[inline]
600    fn drop(&mut self) {
601        unsafe { self.0.as_ref()._unref() };
602    }
603}
604
605impl<N: NativeRefCounted + NativePartialEq> PartialEq for RCHandle<N> {
606    fn eq(&self, rhs: &Self) -> bool {
607        self.native().eq(rhs.native())
608    }
609}
610
611/// A trait that consumes self and converts it to a ptr to the native type.
612pub(crate) trait IntoPtr<N> {
613    fn into_ptr(self) -> *mut N;
614}
615
616impl<N: NativeRefCounted> IntoPtr<N> for RCHandle<N> {
617    fn into_ptr(self) -> *mut N {
618        let ptr = self.0.as_ptr();
619        mem::forget(self);
620        ptr
621    }
622}
623
624/// A trait that consumes self and converts it to a ptr to the native type or null.
625pub(crate) trait IntoPtrOrNull {
626    type Native;
627    fn into_ptr_or_null(self) -> *mut Self::Native;
628}
629
630impl<N: NativeRefCounted> IntoPtrOrNull for Option<RCHandle<N>> {
631    type Native = N;
632    fn into_ptr_or_null(self) -> *mut N {
633        self.map(|rc| rc.into_ptr()).unwrap_or(ptr::null_mut())
634    }
635}
636
637/// Tag the type to automatically implement get() functions for
638/// all Index implementations.
639pub trait IndexGet {}
640
641/// Tag the type to automatically implement get() and set() functions
642/// for all Index & IndexMut implementation for that type.
643pub trait IndexSet {}
644
645pub trait IndexGetter<I, O: Copy> {
646    // TODO: Not sure why clippy 1.78-beta.1 complains about this one.
647    #[allow(unused)]
648    fn get(&self, index: I) -> O;
649}
650
651impl<T, I, O: Copy> IndexGetter<I, O> for T
652where
653    T: Index<I, Output = O> + IndexGet,
654{
655    fn get(&self, index: I) -> O {
656        self[index]
657    }
658}
659
660pub trait IndexSetter<I, O: Copy> {
661    fn set(&mut self, index: I, value: O) -> &mut Self;
662}
663
664impl<T, I, O: Copy> IndexSetter<I, O> for T
665where
666    T: IndexMut<I, Output = O> + IndexSet,
667{
668    fn set(&mut self, index: I, value: O) -> &mut Self {
669        self[index] = value;
670        self
671    }
672}
673
674/// Trait to mark a native type that can be treated a Rust type _inplace_ with the same size and
675/// field layout.
676pub trait NativeTransmutable<NT: Sized>: Sized
677where
678    Self: Sized,
679{
680    /// Provides access to the native value through a
681    /// transmuted reference to the Rust value.
682    fn native(&self) -> &NT {
683        unsafe { transmute_ref(self) }
684    }
685
686    /// Provides mutable access to the native value through a transmuted reference to the Rust
687    /// value.
688    fn native_mut(&mut self) -> &mut NT {
689        unsafe { transmute_ref_mut(self) }
690    }
691
692    /// Copies the native value to an equivalent Rust value.
693    ///
694    /// The `_c` suffix is to remind callers that values that requires C++ ABI features can't be
695    /// used here.
696    fn from_native_c(nt: NT) -> Self {
697        let r = unsafe { mem::transmute_copy::<NT, Self>(&nt) };
698        // don't drop, the Rust type takes over.
699        mem::forget(nt);
700        r
701    }
702
703    /// Copies the rust type to an equivalent instance of the native type.
704    fn into_native(self) -> NT {
705        let r = unsafe { mem::transmute_copy::<Self, NT>(&self) };
706        // don't drop, the native type takes over.
707        mem::forget(self);
708        r
709    }
710
711    /// Returns a reference to the Rust value by transmuting a reference to the native value.
712    fn from_native_ref(nt: &NT) -> &Self {
713        unsafe { transmute_ref(nt) }
714    }
715
716    /// Returns a reference to the Rust array reference by transmuting a reference to the native
717    /// array.
718    fn from_native_array_ref<const N: usize>(nt: &[NT; N]) -> &[Self; N] {
719        unsafe { transmute_ref(nt) }
720    }
721
722    /// Returns a reference to the Rust value through a transmuted reference to the native mutable
723    /// value.
724    fn from_native_ref_mut(nt: &mut NT) -> &mut Self {
725        unsafe { transmute_ref_mut(nt) }
726    }
727
728    /// Converts a pointer to a native value into a pointer to the Rust value.
729    fn from_native_ptr(np: *const NT) -> *const Self {
730        np as _
731    }
732
733    /// Converts a pointer to a mutable native value into a pointer to the mutable Rust value.
734    fn from_native_ptr_mut(np: *mut NT) -> *mut Self {
735        np as _
736    }
737
738    fn construct(construct: impl FnOnce(*mut NT)) -> Self {
739        Self::try_construct(|i| {
740            construct(i);
741            true
742        })
743        .unwrap()
744    }
745
746    fn try_construct(construct: impl FnOnce(*mut NT) -> bool) -> Option<Self> {
747        self::try_construct(construct).map(|n| Self::from_native_c(n.into_inner()))
748    }
749}
750
751/// Tests if T1 and T2 do have the same size and alignment.
752pub(crate) const fn assert_layout_compatible<T1, T2>() {
753    assert!(
754        mem::size_of::<T1>() == mem::size_of::<T2>(),
755        "Type layout verification failed: Size mismatch"
756    );
757    assert!(
758        mem::align_of::<T1>() == mem::align_of::<T2>(),
759        "Type layout verification failed: Alignment mismatch"
760    );
761}
762
763pub(crate) trait NativeTransmutableSliceAccess<NT: Sized> {
764    fn native(&self) -> &[NT];
765    fn native_mut(&mut self) -> &mut [NT];
766}
767
768impl<NT, ElementT> NativeTransmutableSliceAccess<NT> for [ElementT]
769where
770    ElementT: NativeTransmutable<NT>,
771{
772    fn native(&self) -> &[NT] {
773        unsafe { &*(self as *const [ElementT] as *const [NT]) }
774    }
775
776    fn native_mut(&mut self) -> &mut [NT] {
777        unsafe { &mut *(self as *mut [ElementT] as *mut [NT]) }
778    }
779}
780
781impl<NT, RustT> NativeTransmutable<Option<NT>> for Option<RustT> where RustT: NativeTransmutable<NT> {}
782
783impl<NT, RustT> NativeTransmutable<Option<&[NT]>> for Option<&[RustT]> where
784    RustT: NativeTransmutable<NT>
785{
786}
787
788pub(crate) trait NativeTransmutableOptionSliceAccessMut<NT: Sized> {
789    fn native_mut(&mut self) -> &mut Option<&mut [NT]>;
790}
791
792impl<NT, RustT> NativeTransmutableOptionSliceAccessMut<NT> for Option<&mut [RustT]>
793where
794    RustT: NativeTransmutable<NT>,
795{
796    fn native_mut(&mut self) -> &mut Option<&mut [NT]> {
797        unsafe { transmute_ref_mut(self) }
798    }
799}
800
801//
802// Convenience functions to access Option<&[]> as optional ptr (opt_ptr)
803// that may be null.
804//
805
806pub(crate) trait AsPointerOrNull<PointerT> {
807    fn as_ptr_or_null(&self) -> *const PointerT;
808}
809
810pub(crate) trait AsPointerOrNullMut<PointerT>: AsPointerOrNull<PointerT> {
811    fn as_ptr_or_null_mut(&mut self) -> *mut PointerT;
812}
813
814impl<E> AsPointerOrNull<E> for Option<E> {
815    fn as_ptr_or_null(&self) -> *const E {
816        match self {
817            Some(e) => e,
818            None => ptr::null(),
819        }
820    }
821}
822
823impl<E> AsPointerOrNullMut<E> for Option<E> {
824    fn as_ptr_or_null_mut(&mut self) -> *mut E {
825        match self {
826            Some(e) => e,
827            None => ptr::null_mut(),
828        }
829    }
830}
831
832impl<E> AsPointerOrNull<E> for Option<&[E]> {
833    fn as_ptr_or_null(&self) -> *const E {
834        match self {
835            Some(slice) => slice.as_ptr(),
836            None => ptr::null(),
837        }
838    }
839}
840
841impl<E> AsPointerOrNull<E> for Option<&mut [E]> {
842    fn as_ptr_or_null(&self) -> *const E {
843        match self {
844            Some(slice) => slice.as_ptr(),
845            None => ptr::null(),
846        }
847    }
848}
849
850impl<E> AsPointerOrNullMut<E> for Option<&mut [E]> {
851    fn as_ptr_or_null_mut(&mut self) -> *mut E {
852        match self {
853            Some(slice) => slice.as_mut_ptr(),
854            None => ptr::null_mut(),
855        }
856    }
857}
858
859impl<E> AsPointerOrNull<E> for Option<&Vec<E>> {
860    fn as_ptr_or_null(&self) -> *const E {
861        match self {
862            Some(v) => v.as_ptr(),
863            None => ptr::null(),
864        }
865    }
866}
867
868impl<E> AsPointerOrNull<E> for Option<Vec<E>> {
869    fn as_ptr_or_null(&self) -> *const E {
870        match self {
871            Some(v) => v.as_ptr(),
872            None => ptr::null(),
873        }
874    }
875}
876
877impl<E> AsPointerOrNullMut<E> for Option<Vec<E>> {
878    fn as_ptr_or_null_mut(&mut self) -> *mut E {
879        match self {
880            Some(v) => v.as_mut_ptr(),
881            None => ptr::null_mut(),
882        }
883    }
884}
885
886// Wraps a handle so that the Rust's borrow checker assumes it represents
887// something that borrows something else.
888#[repr(transparent)]
889pub struct Borrows<'a, H>(H, PhantomData<&'a ()>);
890
891impl<H> Deref for Borrows<'_, H> {
892    type Target = H;
893    fn deref(&self) -> &Self::Target {
894        &self.0
895    }
896}
897
898// TODO: this is most likely unsafe because someone could replace the
899// value the reference is pointing to.
900impl<H> DerefMut for Borrows<'_, H> {
901    fn deref_mut(&mut self) -> &mut Self::Target {
902        &mut self.0
903    }
904}
905
906impl<H> Borrows<'_, H> {
907    /// Notify that the borrowed dependency is not referred to anymore and return the handle.
908    /// # Safety
909    /// The borrowed dependency must be removed before calling `release()`.
910    pub unsafe fn release(self) -> H {
911        self.0
912    }
913}
914
915pub(crate) trait BorrowsFrom: Sized {
916    fn borrows<D: ?Sized>(self, _dep: &D) -> Borrows<Self>;
917}
918
919impl<T: Sized> BorrowsFrom for T {
920    fn borrows<D: ?Sized>(self, _dep: &D) -> Borrows<Self> {
921        Borrows(self, PhantomData)
922    }
923}
924
925impl<H> Borrows<'_, H> {
926    pub(crate) unsafe fn unchecked_new(h: H) -> Self {
927        Self(h, PhantomData)
928    }
929}
930
931/// Declares a base class for a native type.
932pub trait NativeBase<Base> {
933    fn base(&self) -> &Base {
934        unsafe { &*(self as *const Self as *const Base) }
935    }
936
937    fn base_mut(&mut self) -> &mut Base {
938        unsafe { &mut *(self as *mut Self as *mut Base) }
939    }
940}
941
942pub struct Sendable<H: ConditionallySend>(H);
943unsafe impl<H: ConditionallySend> Send for Sendable<H> {}
944
945impl<H: ConditionallySend> Sendable<H> {
946    #[deprecated(note = "Use Sendable::into_inner() instead")]
947    pub fn unwrap(self) -> H {
948        self.0
949    }
950
951    pub fn into_inner(self) -> H {
952        self.0
953    }
954}
955
956impl<H> Debug for Sendable<H>
957where
958    H: Debug + ConditionallySend,
959{
960    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
961        f.debug_tuple("Sendable").field(&self.0).finish()
962    }
963}
964
965pub trait ConditionallySend: Sized {
966    /// Returns `true` if the handle can be sent to another thread.
967    fn can_send(&self) -> bool;
968    /// Wrap the handle in a type that can be sent to another thread and unwrapped there.
969    ///
970    /// Guaranteed to succeed of can_send() returns `true`.
971    fn wrap_send(self) -> Result<Sendable<Self>, Self>;
972}
973
974/// `RCHandle<H>` is conditionally Send and can be sent to
975/// another thread when its reference count is 1.
976impl<H: NativeRefCountedBase> ConditionallySend for RCHandle<H> {
977    fn can_send(&self) -> bool {
978        self.native().unique()
979    }
980
981    fn wrap_send(self) -> Result<Sendable<Self>, Self> {
982        if self.can_send() {
983            Ok(Sendable(self))
984        } else {
985            Err(self)
986        }
987    }
988}
989
990/// Functions that are (supposedly) _safer_ variants of the ones Rust provides.
991pub(crate) mod safer {
992    use core::slice;
993    use std::ptr;
994
995    /// Invokes [slice::from_raw_parts] with the `ptr` only when `len` != 0, otherwise passes
996    /// `ptr::NonNull::dangling()` as recommended.
997    ///
998    /// Panics if `len` != 0 and `ptr` is `null`.
999    pub unsafe fn from_raw_parts<'a, T>(ptr: *const T, len: usize) -> &'a [T] {
1000        let ptr = if len == 0 {
1001            ptr::NonNull::dangling().as_ptr()
1002        } else {
1003            assert!(!ptr.is_null());
1004            ptr
1005        };
1006        slice::from_raw_parts(ptr, len)
1007    }
1008
1009    /// Invokes [slice::from_raw_parts_mut] with the `ptr` only if `len` != 0, otherwise passes
1010    /// `ptr::NonNull::dangling()` as recommended.
1011    ///
1012    /// Panics if `len` != 0 and `ptr` is `null`.
1013    pub unsafe fn from_raw_parts_mut<'a, T>(ptr: *mut T, len: usize) -> &'a mut [T] {
1014        let ptr = if len == 0 {
1015            ptr::NonNull::dangling().as_ptr() as *mut _
1016        } else {
1017            assert!(!ptr.is_null());
1018            ptr
1019        };
1020        slice::from_raw_parts_mut(ptr, len)
1021    }
1022}
1023
1024#[cfg(test)]
1025mod tests {
1026    struct PanicOnDrop {}
1027    impl Drop for PanicOnDrop {
1028        fn drop(&mut self) {
1029            panic!("Shall not drop")
1030        }
1031    }
1032    #[test]
1033
1034    fn try_construct_does_not_drop_when_construction_attempt_fails() {
1035        _ = super::try_construct::<PanicOnDrop>(|_| false);
1036    }
1037}