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(|| 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]
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 #[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 pub(crate) fn from_unshared_ptr_ref(n: &*mut N) -> &Option<Self> {
534 unsafe { transmute_ref(n) }
535 }
536
537 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 #[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 fn native(&self) -> &N {
580 unsafe { self.0.as_ref() }
581 }
582
583 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 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
611pub(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
624pub(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
637pub trait IndexGet {}
640
641pub trait IndexSet {}
644
645pub trait IndexGetter<I, O: Copy> {
646 #[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
674pub trait NativeTransmutable<NT: Sized>: Sized
677where
678 Self: Sized,
679{
680 fn native(&self) -> &NT {
683 unsafe { transmute_ref(self) }
684 }
685
686 fn native_mut(&mut self) -> &mut NT {
689 unsafe { transmute_ref_mut(self) }
690 }
691
692 fn from_native_c(nt: NT) -> Self {
697 let r = unsafe { mem::transmute_copy::<NT, Self>(&nt) };
698 mem::forget(nt);
700 r
701 }
702
703 fn into_native(self) -> NT {
705 let r = unsafe { mem::transmute_copy::<Self, NT>(&self) };
706 mem::forget(self);
708 r
709 }
710
711 fn from_native_ref(nt: &NT) -> &Self {
713 unsafe { transmute_ref(nt) }
714 }
715
716 fn from_native_array_ref<const N: usize>(nt: &[NT; N]) -> &[Self; N] {
719 unsafe { transmute_ref(nt) }
720 }
721
722 fn from_native_ref_mut(nt: &mut NT) -> &mut Self {
725 unsafe { transmute_ref_mut(nt) }
726 }
727
728 fn from_native_ptr(np: *const NT) -> *const Self {
730 np as _
731 }
732
733 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
751pub(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
801pub(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#[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
898impl<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 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
931pub 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 fn can_send(&self) -> bool;
968 fn wrap_send(self) -> Result<Sendable<Self>, Self>;
972}
973
974impl<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
990pub(crate) mod safer {
992 use core::slice;
993 use std::ptr;
994
995 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 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}