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 C_SkRefCntBase_ref, C_SkRefCntBase_unique, C_SkRefCntBase_unref, SkRefCnt, SkRefCntBase, sk_sp,
14};
15
16pub(crate) unsafe fn transmute_ref<FromT, ToT>(from: &FromT) -> &ToT {
18 unsafe {
19 assert_layout_compatible::<FromT, ToT>();
20 &*(from as *const FromT as *const ToT)
21 }
22}
23
24pub(crate) unsafe fn transmute_ref_mut<FromT, ToT>(from: &mut FromT) -> &mut ToT {
25 unsafe {
26 assert_layout_compatible::<FromT, ToT>();
27 &mut *(from as *mut FromT as *mut ToT)
28 }
29}
30
31pub(crate) trait IntoNonNull {
32 type Target;
33 fn into_non_null(self) -> Option<ptr::NonNull<Self::Target>>;
34}
35
36impl<T> IntoNonNull for *const T {
37 type Target = T;
38
39 fn into_non_null(self) -> Option<ptr::NonNull<Self::Target>> {
40 ptr::NonNull::new(self as *mut T)
41 }
42}
43
44impl<T> IntoNonNull for *mut T {
45 type Target = T;
46
47 fn into_non_null(self) -> Option<ptr::NonNull<Self::Target>> {
48 ptr::NonNull::new(self)
49 }
50}
51
52#[cfg(test)]
53pub(crate) trait RefCount {
54 fn ref_cnt(&self) -> usize;
55}
56
57#[cfg(test)]
58impl RefCount for SkRefCntBase {
59 #[allow(clippy::cast_ptr_alignment)]
63 fn ref_cnt(&self) -> usize {
64 unsafe {
65 let ptr: *const i32 = &self.fRefCnt as *const _ as *const i32;
66 (*ptr).try_into().unwrap()
67 }
68 }
69}
70
71impl NativeBase<SkRefCntBase> for SkRefCnt {}
72
73#[cfg(test)]
74impl RefCount for SkRefCnt {
75 fn ref_cnt(&self) -> usize {
76 self.base().ref_cnt()
77 }
78}
79
80#[cfg(test)]
81impl RefCount for skia_bindings::SkNVRefCnt {
82 #[allow(clippy::cast_ptr_alignment)]
83 fn ref_cnt(&self) -> usize {
84 unsafe {
85 let ptr: *const i32 = &self.fRefCnt as *const _ as *const i32;
86 (*ptr).try_into().unwrap()
87 }
88 }
89}
90
91pub trait NativeRefCounted: Sized {
92 fn _ref(&self);
93 fn _unref(&self);
94 fn unique(&self) -> bool;
95 fn _ref_cnt(&self) -> usize {
96 unimplemented!();
97 }
98}
99
100impl NativeRefCounted for SkRefCntBase {
101 fn _ref(&self) {
102 unsafe { C_SkRefCntBase_ref(self) }
103 }
104
105 fn _unref(&self) {
106 unsafe { C_SkRefCntBase_unref(self) }
107 }
108
109 fn unique(&self) -> bool {
110 unsafe { C_SkRefCntBase_unique(self) }
111 }
112
113 #[allow(clippy::cast_ptr_alignment)]
114 fn _ref_cnt(&self) -> usize {
115 unsafe {
116 let ptr: *const i32 = &self.fRefCnt as *const _ as *const i32;
117 (*ptr).try_into().unwrap()
118 }
119 }
120}
121
122pub trait NativeRefCountedBase {
126 type Base: NativeRefCounted;
127
128 fn ref_counted_base(&self) -> &Self::Base {
133 unsafe { &*(self as *const _ as *const Self::Base) }
134 }
135}
136
137impl<Native, Base: NativeRefCounted> NativeRefCounted for Native
138where
139 Native: NativeRefCountedBase<Base = Base>,
140{
141 fn _ref(&self) {
142 self.ref_counted_base()._ref();
143 }
144
145 fn _unref(&self) {
146 self.ref_counted_base()._unref();
147 }
148
149 fn unique(&self) -> bool {
150 self.ref_counted_base().unique()
151 }
152
153 fn _ref_cnt(&self) -> usize {
154 self.ref_counted_base()._ref_cnt()
155 }
156}
157
158pub trait NativeAccess {
160 type Native;
161 fn native(&self) -> &Self::Native;
163
164 fn native_mut(&mut self) -> &mut Self::Native;
166
167 unsafe fn native_mut_force(&self) -> *mut Self::Native {
169 self.native() as *const Self::Native as *mut Self::Native
170 }
171}
172
173pub trait NativeDrop {
175 fn drop(&mut self);
176}
177
178pub trait NativeClone {
180 fn clone(&self) -> Self;
181}
182
183pub trait NativePartialEq {
186 fn eq(&self, rhs: &Self) -> bool;
187}
188
189pub trait NativeHash {
192 fn hash<H: Hasher>(&self, state: &mut H);
193}
194
195#[repr(transparent)]
199pub struct Handle<N: NativeDrop>(
200 UnsafeCell<N>,
203 PhantomData<*const ()>,
206);
207
208impl<N: NativeDrop> AsRef<Handle<N>> for Handle<N> {
209 fn as_ref(&self) -> &Self {
210 self
211 }
212}
213
214impl<N: NativeDrop> Handle<N> {
215 #[must_use]
217 pub(crate) fn from_native_c(n: N) -> Self {
218 Handle(n.into(), PhantomData)
219 }
220
221 #[must_use]
223 pub(crate) fn from_native_ref(n: &N) -> &Self {
224 unsafe { transmute_ref(n) }
225 }
226
227 #[must_use]
229 pub(crate) fn from_native_ref_mut(n: &mut N) -> &mut Self {
230 unsafe { transmute_ref_mut(n) }
231 }
232
233 #[must_use]
235 pub(crate) fn from_native_ptr(np: *const N) -> *const Self {
236 np as _
237 }
238
239 #[allow(unused)]
241 #[must_use]
242 pub(crate) fn from_native_ptr_mut(np: *mut N) -> *mut Self {
243 np as _
244 }
245
246 #[must_use]
250 pub(crate) fn construct(construct: impl FnOnce(*mut N)) -> Self {
251 Self::try_construct(|i| {
252 construct(i);
253 true
254 })
255 .unwrap()
256 }
257
258 pub(crate) fn try_construct(construct: impl FnOnce(*mut N) -> bool) -> Option<Self> {
259 self::try_construct(construct).map(|n| Self::from_native_c(n.into_inner()))
260 }
261
262 #[must_use]
265 pub(crate) fn replace_native(mut self, native: &mut N) -> Self {
266 mem::swap(self.0.get_mut(), native);
267 self
268 }
269
270 #[must_use]
272 pub(crate) fn into_native(mut self) -> N {
273 let r = mem::replace(&mut self.0, unsafe { mem::zeroed() });
274 mem::forget(self);
275 r.into_inner()
276 }
277}
278
279pub(crate) trait ReplaceWith<Other> {
280 fn replace_with(&mut self, other: Other) -> Other;
281}
282
283impl<N: NativeDrop> ReplaceWith<Handle<N>> for N {
284 fn replace_with(&mut self, other: Handle<N>) -> Handle<N> {
285 other.replace_native(self)
286 }
287}
288
289#[must_use]
292pub(crate) fn construct<N>(construct: impl FnOnce(*mut N)) -> N {
293 try_construct(|i| {
294 construct(i);
295 true
296 })
297 .unwrap()
298 .into_inner()
299}
300
301#[must_use]
302pub(crate) fn try_construct<N>(construct: impl FnOnce(*mut N) -> bool) -> Option<UnsafeCell<N>> {
303 let mut instance = mem::MaybeUninit::uninit();
304 construct(instance.as_mut_ptr()).then(|| unsafe { instance.assume_init() }.into())
305}
306
307impl<N: NativeDrop> Drop for Handle<N> {
308 fn drop(&mut self) {
309 self.0.get_mut().drop()
310 }
311}
312
313impl<N: NativeDrop> NativeAccess for Handle<N> {
314 type Native = N;
315
316 fn native(&self) -> &N {
317 unsafe { &*(self.0.get()) }
318 }
319
320 fn native_mut(&mut self) -> &mut N {
321 self.0.get_mut()
322 }
323}
324
325impl<N: NativeDrop + NativeClone> Clone for Handle<N> {
326 fn clone(&self) -> Self {
327 Self::from_native_c(self.native().clone())
328 }
329}
330
331impl<N: NativeDrop + NativePartialEq> PartialEq for Handle<N> {
332 fn eq(&self, rhs: &Self) -> bool {
333 self.native().eq(rhs.native())
334 }
335}
336
337impl<N: NativeDrop + NativeHash> Hash for Handle<N> {
338 fn hash<H: Hasher>(&self, state: &mut H) {
339 self.native().hash(state);
340 }
341}
342
343pub(crate) trait NativeSliceAccess<N: NativeDrop> {
344 fn native(&self) -> &[N];
345 fn native_mut(&mut self) -> &mut [N];
346}
347
348impl<N: NativeDrop> NativeSliceAccess<N> for [Handle<N>] {
349 fn native(&self) -> &[N] {
350 let ptr = self.first().native_ptr_or_null();
351 unsafe { slice::from_raw_parts(ptr, self.len()) }
352 }
353
354 fn native_mut(&mut self) -> &mut [N] {
355 let ptr = self.first_mut().native_ptr_or_null_mut();
356 unsafe { slice::from_raw_parts_mut(ptr, self.len()) }
357 }
358}
359
360pub(crate) trait NativePointerOrNull {
363 type Native;
364
365 fn native_ptr_or_null(&self) -> *const Self::Native;
366 unsafe fn native_ptr_or_null_mut_force(&self) -> *mut Self::Native;
367}
368
369pub(crate) trait NativePointerOrNullMut {
370 type Native;
371
372 fn native_ptr_or_null_mut(&mut self) -> *mut Self::Native;
373}
374
375impl<H, N> NativePointerOrNull for Option<&H>
376where
377 H: NativeAccess<Native = N>,
378{
379 type Native = N;
380
381 fn native_ptr_or_null(&self) -> *const N {
382 match self {
383 Some(handle) => handle.native(),
384 None => ptr::null(),
385 }
386 }
387
388 unsafe fn native_ptr_or_null_mut_force(&self) -> *mut N {
389 unsafe {
390 match self {
391 Some(handle) => handle.native_mut_force(),
392 None => ptr::null_mut(),
393 }
394 }
395 }
396}
397
398impl<H, N> NativePointerOrNullMut for Option<&mut H>
399where
400 H: NativeAccess<Native = N>,
401{
402 type Native = N;
403
404 fn native_ptr_or_null_mut(&mut self) -> *mut N {
405 match self {
406 Some(handle) => handle.native_mut(),
407 None => ptr::null_mut(),
408 }
409 }
410}
411
412pub(crate) trait NativePointerOrNullMut2<N> {
413 fn native_ptr_or_null_mut(&mut self) -> *mut N;
414}
415
416pub(crate) trait NativePointerOrNull2<N> {
417 fn native_ptr_or_null(&self) -> *const N;
418}
419
420impl<H, N> NativePointerOrNull2<N> for Option<&H>
421where
422 H: NativeTransmutable<N>,
423{
424 fn native_ptr_or_null(&self) -> *const N {
425 match self {
426 Some(handle) => handle.native(),
427 None => ptr::null(),
428 }
429 }
430}
431
432impl<H, N> NativePointerOrNullMut2<N> for Option<&mut H>
433where
434 H: NativeTransmutable<N>,
435{
436 fn native_ptr_or_null_mut(&mut self) -> *mut N {
437 match self {
438 Some(handle) => handle.native_mut(),
439 None => ptr::null_mut(),
440 }
441 }
442}
443
444#[repr(transparent)]
447pub struct RefHandle<N: NativeDrop>(ptr::NonNull<N>);
448
449impl<N: NativeDrop> Drop for RefHandle<N> {
450 fn drop(&mut self) {
451 self.native_mut().drop()
452 }
453}
454
455impl<N: NativeDrop + NativePartialEq> PartialEq for RefHandle<N> {
456 fn eq(&self, rhs: &Self) -> bool {
457 self.native().eq(rhs.native())
458 }
459}
460
461impl<N: NativeDrop> NativeAccess for RefHandle<N> {
462 type Native = N;
463
464 fn native(&self) -> &N {
465 unsafe { self.0.as_ref() }
466 }
467 fn native_mut(&mut self) -> &mut N {
468 unsafe { self.0.as_mut() }
469 }
470}
471
472impl<N: NativeDrop> RefHandle<N> {
473 pub(crate) fn from_ptr(ptr: *mut N) -> Option<Self> {
478 ptr::NonNull::new(ptr).map(Self)
479 }
480
481 pub(crate) fn into_ptr(self) -> *mut N {
482 let p = self.0.as_ptr();
483 mem::forget(self);
484 p
485 }
486}
487
488#[repr(transparent)]
491pub struct RCHandle<Native: NativeRefCounted>(ptr::NonNull<Native>);
492
493impl<N: NativeRefCounted> From<&RCHandle<N>> for RCHandle<N> {
496 fn from(rch: &RCHandle<N>) -> Self {
497 rch.clone()
498 }
499}
500
501impl<N: NativeRefCounted> AsRef<RCHandle<N>> for RCHandle<N> {
502 fn as_ref(&self) -> &Self {
503 self
504 }
505}
506
507impl<N: NativeRefCounted> RCHandle<N> {
508 #[inline]
514 pub(crate) fn from_ptr(ptr: *mut N) -> Option<Self> {
515 ptr::NonNull::new(ptr).map(Self)
516 }
517
518 #[inline]
519 pub(crate) fn from_ptr_const(ptr: *const N) -> Option<Self> {
520 ptr::NonNull::new(ptr as *mut N).map(Self)
521 }
522
523 #[inline]
530 pub(crate) fn from_unshared_ptr(ptr: *mut N) -> Option<Self> {
531 ptr::NonNull::new(ptr).map(|ptr| {
532 unsafe { ptr.as_ref()._ref() };
533 Self(ptr)
534 })
535 }
536
537 pub(crate) fn from_unshared_ptr_ref(n: &*mut N) -> &Option<Self> {
540 unsafe { transmute_ref(n) }
541 }
542
543 pub(crate) fn from_non_null_sp_slice(sp_slice: &[sk_sp<N>]) -> &[Self] {
545 assert_layout_compatible::<sk_sp<N>, Self>();
546 assert!(sp_slice.iter().all(|v| !v.fPtr.is_null()));
547 unsafe { mem::transmute(sp_slice) }
548 }
549
550 #[allow(unused)]
552 pub(crate) fn as_ptr(&self) -> &ptr::NonNull<N> {
553 &self.0
554 }
555}
556
557#[cfg(test)]
558mod rc_handle_tests {
559 use std::ptr;
560
561 use skia_bindings::{SkFontMgr, SkTypeface};
562
563 use crate::{FontMgr, Typeface, prelude::NativeAccess};
564
565 #[test]
566 fn rc_native_ref_null() {
567 let f: *mut SkTypeface = ptr::null_mut();
568 let r = Typeface::from_unshared_ptr(f);
569 assert!(r.is_none())
570 }
571
572 #[test]
573 fn rc_native_ref_non_null() {
574 let mut font_mgr = FontMgr::new();
575 let f: *mut SkFontMgr = font_mgr.native_mut();
576 let r = FontMgr::from_unshared_ptr(f);
577 assert!(r.is_some())
578 }
579}
580
581impl<N: NativeRefCounted> NativeAccess for RCHandle<N> {
582 type Native = N;
583
584 fn native(&self) -> &N {
586 unsafe { self.0.as_ref() }
587 }
588
589 fn native_mut(&mut self) -> &mut N {
591 unsafe { self.0.as_mut() }
592 }
593}
594
595impl<N: NativeRefCounted> Clone for RCHandle<N> {
596 fn clone(&self) -> Self {
597 let ptr = self.0;
599 unsafe { ptr.as_ref()._ref() };
600 Self(ptr)
601 }
602}
603
604impl<N: NativeRefCounted> Drop for RCHandle<N> {
605 #[inline]
606 fn drop(&mut self) {
607 unsafe { self.0.as_ref()._unref() };
608 }
609}
610
611impl<N: NativeRefCounted + NativePartialEq> PartialEq for RCHandle<N> {
612 fn eq(&self, rhs: &Self) -> bool {
613 self.native().eq(rhs.native())
614 }
615}
616
617pub(crate) trait IntoPtr<N> {
619 fn into_ptr(self) -> *mut N;
620}
621
622impl<N: NativeRefCounted> IntoPtr<N> for RCHandle<N> {
623 fn into_ptr(self) -> *mut N {
624 let ptr = self.0.as_ptr();
625 mem::forget(self);
626 ptr
627 }
628}
629
630pub(crate) trait IntoPtrOrNull {
632 type Native;
633 fn into_ptr_or_null(self) -> *mut Self::Native;
634}
635
636impl<N: NativeRefCounted> IntoPtrOrNull for Option<RCHandle<N>> {
637 type Native = N;
638 fn into_ptr_or_null(self) -> *mut N {
639 self.map(|rc| rc.into_ptr()).unwrap_or(ptr::null_mut())
640 }
641}
642
643pub trait IndexGet {}
646
647pub trait IndexSet {}
650
651pub trait IndexGetter<I, O: Copy> {
652 #[allow(unused)]
654 fn get(&self, index: I) -> O;
655}
656
657impl<T, I, O: Copy> IndexGetter<I, O> for T
658where
659 T: Index<I, Output = O> + IndexGet,
660{
661 fn get(&self, index: I) -> O {
662 self[index]
663 }
664}
665
666pub trait IndexSetter<I, O: Copy> {
667 fn set(&mut self, index: I, value: O) -> &mut Self;
668}
669
670impl<T, I, O: Copy> IndexSetter<I, O> for T
671where
672 T: IndexMut<I, Output = O> + IndexSet,
673{
674 fn set(&mut self, index: I, value: O) -> &mut Self {
675 self[index] = value;
676 self
677 }
678}
679
680pub trait NativeTransmutable<NT: Sized>: Sized
683where
684 Self: Sized,
685{
686 fn native(&self) -> &NT {
689 unsafe { transmute_ref(self) }
690 }
691
692 fn native_mut(&mut self) -> &mut NT {
695 unsafe { transmute_ref_mut(self) }
696 }
697
698 fn from_native_c(nt: NT) -> Self {
703 let r = unsafe { mem::transmute_copy::<NT, Self>(&nt) };
704 mem::forget(nt);
706 r
707 }
708
709 fn into_native(self) -> NT {
711 let r = unsafe { mem::transmute_copy::<Self, NT>(&self) };
712 mem::forget(self);
714 r
715 }
716
717 fn from_native_ref(nt: &NT) -> &Self {
719 unsafe { transmute_ref(nt) }
720 }
721
722 fn from_native_array_ref<const N: usize>(nt: &[NT; N]) -> &[Self; N] {
725 unsafe { transmute_ref(nt) }
726 }
727
728 fn from_native_ref_mut(nt: &mut NT) -> &mut Self {
731 unsafe { transmute_ref_mut(nt) }
732 }
733
734 fn from_native_ptr(np: *const NT) -> *const Self {
736 np as _
737 }
738
739 fn from_native_ptr_mut(np: *mut NT) -> *mut Self {
741 np as _
742 }
743
744 fn construct(construct: impl FnOnce(*mut NT)) -> Self {
745 Self::try_construct(|i| {
746 construct(i);
747 true
748 })
749 .unwrap()
750 }
751
752 fn try_construct(construct: impl FnOnce(*mut NT) -> bool) -> Option<Self> {
753 self::try_construct(construct).map(|n| Self::from_native_c(n.into_inner()))
754 }
755}
756
757pub(crate) const fn assert_layout_compatible<T1, T2>() {
759 assert!(
760 mem::size_of::<T1>() == mem::size_of::<T2>(),
761 "Type layout verification failed: Size mismatch"
762 );
763 assert!(
764 mem::align_of::<T1>() == mem::align_of::<T2>(),
765 "Type layout verification failed: Alignment mismatch"
766 );
767}
768
769pub(crate) trait NativeTransmutableSliceAccess<NT: Sized> {
770 fn native(&self) -> &[NT];
771 fn native_mut(&mut self) -> &mut [NT];
772}
773
774impl<NT, ElementT> NativeTransmutableSliceAccess<NT> for [ElementT]
775where
776 ElementT: NativeTransmutable<NT>,
777{
778 fn native(&self) -> &[NT] {
779 unsafe { &*(self as *const [ElementT] as *const [NT]) }
780 }
781
782 fn native_mut(&mut self) -> &mut [NT] {
783 unsafe { &mut *(self as *mut [ElementT] as *mut [NT]) }
784 }
785}
786
787impl<NT, RustT> NativeTransmutable<Option<NT>> for Option<RustT> where RustT: NativeTransmutable<NT> {}
788
789impl<NT, RustT> NativeTransmutable<Option<&[NT]>> for Option<&[RustT]> where
790 RustT: NativeTransmutable<NT>
791{
792}
793
794pub(crate) trait NativeTransmutableOptionSliceAccessMut<NT: Sized> {
795 fn native_mut(&mut self) -> &mut Option<&mut [NT]>;
796}
797
798impl<NT, RustT> NativeTransmutableOptionSliceAccessMut<NT> for Option<&mut [RustT]>
799where
800 RustT: NativeTransmutable<NT>,
801{
802 fn native_mut(&mut self) -> &mut Option<&mut [NT]> {
803 unsafe { transmute_ref_mut(self) }
804 }
805}
806
807pub(crate) trait AsPointerOrNull<PointerT> {
813 fn as_ptr_or_null(&self) -> *const PointerT;
814}
815
816pub(crate) trait AsPointerOrNullMut<PointerT>: AsPointerOrNull<PointerT> {
817 fn as_ptr_or_null_mut(&mut self) -> *mut PointerT;
818}
819
820impl<E> AsPointerOrNull<E> for Option<E> {
821 fn as_ptr_or_null(&self) -> *const E {
822 match self {
823 Some(e) => e,
824 None => ptr::null(),
825 }
826 }
827}
828
829impl<E> AsPointerOrNullMut<E> for Option<E> {
830 fn as_ptr_or_null_mut(&mut self) -> *mut E {
831 match self {
832 Some(e) => e,
833 None => ptr::null_mut(),
834 }
835 }
836}
837
838impl<E> AsPointerOrNull<E> for Option<&[E]> {
839 fn as_ptr_or_null(&self) -> *const E {
840 match self {
841 Some(slice) => slice.as_ptr(),
842 None => ptr::null(),
843 }
844 }
845}
846
847impl<E> AsPointerOrNull<E> for Option<&mut [E]> {
848 fn as_ptr_or_null(&self) -> *const E {
849 match self {
850 Some(slice) => slice.as_ptr(),
851 None => ptr::null(),
852 }
853 }
854}
855
856impl<E> AsPointerOrNullMut<E> for Option<&mut [E]> {
857 fn as_ptr_or_null_mut(&mut self) -> *mut E {
858 match self {
859 Some(slice) => slice.as_mut_ptr(),
860 None => ptr::null_mut(),
861 }
862 }
863}
864
865impl<E> AsPointerOrNull<E> for Option<&Vec<E>> {
866 fn as_ptr_or_null(&self) -> *const E {
867 match self {
868 Some(v) => v.as_ptr(),
869 None => ptr::null(),
870 }
871 }
872}
873
874impl<E> AsPointerOrNull<E> for Option<Vec<E>> {
875 fn as_ptr_or_null(&self) -> *const E {
876 match self {
877 Some(v) => v.as_ptr(),
878 None => ptr::null(),
879 }
880 }
881}
882
883impl<E> AsPointerOrNullMut<E> for Option<Vec<E>> {
884 fn as_ptr_or_null_mut(&mut self) -> *mut E {
885 match self {
886 Some(v) => v.as_mut_ptr(),
887 None => ptr::null_mut(),
888 }
889 }
890}
891
892#[repr(transparent)]
895pub struct Borrows<'a, H>(H, PhantomData<&'a ()>);
896
897impl<H> Deref for Borrows<'_, H> {
898 type Target = H;
899 fn deref(&self) -> &Self::Target {
900 &self.0
901 }
902}
903
904impl<H> DerefMut for Borrows<'_, H> {
907 fn deref_mut(&mut self) -> &mut Self::Target {
908 &mut self.0
909 }
910}
911
912impl<H> Borrows<'_, H> {
913 pub unsafe fn release(self) -> H {
917 self.0
918 }
919}
920
921pub(crate) trait BorrowsFrom: Sized {
922 fn borrows<D: ?Sized>(self, _dep: &D) -> Borrows<Self>;
923}
924
925impl<T: Sized> BorrowsFrom for T {
926 fn borrows<D: ?Sized>(self, _dep: &D) -> Borrows<Self> {
927 Borrows(self, PhantomData)
928 }
929}
930
931impl<H> Borrows<'_, H> {
932 pub(crate) unsafe fn unchecked_new(h: H) -> Self {
933 Self(h, PhantomData)
934 }
935}
936
937pub trait NativeBase<Base> {
939 fn base(&self) -> &Base {
940 unsafe { &*(self as *const Self as *const Base) }
941 }
942
943 fn base_mut(&mut self) -> &mut Base {
944 unsafe { &mut *(self as *mut Self as *mut Base) }
945 }
946}
947
948pub struct Sendable<H: ConditionallySend>(H);
949unsafe impl<H: ConditionallySend> Send for Sendable<H> {}
950
951impl<H: ConditionallySend> Sendable<H> {
952 #[deprecated(note = "Use Sendable::into_inner() instead")]
953 pub fn unwrap(self) -> H {
954 self.0
955 }
956
957 pub fn into_inner(self) -> H {
958 self.0
959 }
960}
961
962impl<H> Debug for Sendable<H>
963where
964 H: Debug + ConditionallySend,
965{
966 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
967 f.debug_tuple("Sendable").field(&self.0).finish()
968 }
969}
970
971pub trait ConditionallySend: Sized {
972 fn can_send(&self) -> bool;
974 fn wrap_send(self) -> Result<Sendable<Self>, Self>;
978}
979
980impl<H: NativeRefCountedBase> ConditionallySend for RCHandle<H> {
983 fn can_send(&self) -> bool {
984 self.native().unique()
985 }
986
987 fn wrap_send(self) -> Result<Sendable<Self>, Self> {
988 if self.can_send() {
989 Ok(Sendable(self))
990 } else {
991 Err(self)
992 }
993 }
994}
995
996pub(crate) mod safer {
998 use core::slice;
999 use std::ptr;
1000
1001 pub unsafe fn from_raw_parts<'a, T>(ptr: *const T, len: usize) -> &'a [T] {
1006 unsafe {
1007 let ptr = if len == 0 {
1008 ptr::NonNull::dangling().as_ptr()
1009 } else {
1010 assert!(!ptr.is_null());
1011 ptr
1012 };
1013 slice::from_raw_parts(ptr, len)
1014 }
1015 }
1016
1017 pub unsafe fn from_raw_parts_mut<'a, T>(ptr: *mut T, len: usize) -> &'a mut [T] {
1022 unsafe {
1023 let ptr = if len == 0 {
1024 ptr::NonNull::dangling().as_ptr() as *mut _
1025 } else {
1026 assert!(!ptr.is_null());
1027 ptr
1028 };
1029 slice::from_raw_parts_mut(ptr, len)
1030 }
1031 }
1032}
1033
1034#[cfg(test)]
1035mod tests {
1036 struct PanicOnDrop {}
1037 impl Drop for PanicOnDrop {
1038 fn drop(&mut self) {
1039 panic!("Shall not drop")
1040 }
1041 }
1042 #[test]
1043
1044 fn try_construct_does_not_drop_when_construction_attempt_fails() {
1045 _ = super::try_construct::<PanicOnDrop>(|_| false);
1046 }
1047}