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
16pub(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 #[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
118pub trait NativeRefCountedBase {
122 type Base: NativeRefCounted;
123
124 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
154pub trait NativeAccess {
156 type Native;
157 fn native(&self) -> &Self::Native;
159
160 fn native_mut(&mut self) -> &mut Self::Native;
162
163 unsafe fn native_mut_force(&self) -> *mut Self::Native {
165 self.native() as *const Self::Native as *mut Self::Native
166 }
167}
168
169pub trait NativeDrop {
171 fn drop(&mut self);
172}
173
174pub trait NativeClone {
176 fn clone(&self) -> Self;
177}
178
179pub trait NativePartialEq {
182 fn eq(&self, rhs: &Self) -> bool;
183}
184
185pub trait NativeHash {
188 fn hash<H: Hasher>(&self, state: &mut H);
189}
190
191#[repr(transparent)]
195pub struct Handle<N: NativeDrop>(
196 UnsafeCell<N>,
199 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 #[must_use]
213 pub(crate) fn from_native_c(n: N) -> Self {
214 Handle(n.into(), PhantomData)
215 }
216
217 #[must_use]
219 pub(crate) fn from_native_ref(n: &N) -> &Self {
220 unsafe { transmute_ref(n) }
221 }
222
223 #[must_use]
225 pub(crate) fn from_native_ref_mut(n: &mut N) -> &mut Self {
226 unsafe { transmute_ref_mut(n) }
227 }
228
229 #[must_use]
231 pub(crate) fn from_native_ptr(np: *const N) -> *const Self {
232 np as _
233 }
234
235 #[allow(unused)]
237 #[must_use]
238 pub(crate) fn from_native_ptr_mut(np: *mut N) -> *mut Self {
239 np as _
240 }
241
242 #[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 #[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 #[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#[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
356pub(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#[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 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#[repr(transparent)]
485pub struct RCHandle<Native: NativeRefCounted>(ptr::NonNull<Native>);
486
487impl<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 #[inline]
508 pub(crate) fn from_ptr(ptr: *mut N) -> Option<Self> {
509 ptr::NonNull::new(ptr).map(Self)
510 }
511
512 #[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 pub(crate) fn from_unshared_ptr_ref(n: &*mut N) -> &Option<Self> {
529 unsafe { transmute_ref(n) }
530 }
531
532 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 #[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 fn native(&self) -> &N {
575 unsafe { self.0.as_ref() }
576 }
577
578 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 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
606pub(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
619pub(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
632pub trait IndexGet {}
635
636pub trait IndexSet {}
639
640pub trait IndexGetter<I, O: Copy> {
641 #[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
669pub trait NativeTransmutable<NT: Sized>: Sized
672where
673 Self: Sized,
674{
675 fn native(&self) -> &NT {
678 unsafe { transmute_ref(self) }
679 }
680
681 fn native_mut(&mut self) -> &mut NT {
684 unsafe { transmute_ref_mut(self) }
685 }
686
687 fn from_native_c(nt: NT) -> Self {
692 let r = unsafe { mem::transmute_copy::<NT, Self>(&nt) };
693 mem::forget(nt);
695 r
696 }
697
698 fn into_native(self) -> NT {
700 let r = unsafe { mem::transmute_copy::<Self, NT>(&self) };
701 mem::forget(self);
703 r
704 }
705
706 fn from_native_ref(nt: &NT) -> &Self {
708 unsafe { transmute_ref(nt) }
709 }
710
711 fn from_native_array_ref<const N: usize>(nt: &[NT; N]) -> &[Self; N] {
714 unsafe { transmute_ref(nt) }
715 }
716
717 fn from_native_ref_mut(nt: &mut NT) -> &mut Self {
720 unsafe { transmute_ref_mut(nt) }
721 }
722
723 fn from_native_ptr(np: *const NT) -> *const Self {
725 np as _
726 }
727
728 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
746pub(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
796pub(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#[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
893impl<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 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
926pub 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 fn can_send(&self) -> bool;
963 fn wrap_send(self) -> Result<Sendable<Self>, Self>;
967}
968
969impl<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
985pub(crate) mod safer {
987 use core::slice;
988 use std::ptr;
989
990 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 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}