facet_core/impls/core/
nonnull.rs1use core::ptr::NonNull;
2
3use crate::{
4 Def, Facet, HashProxy, KnownPointer, OxPtrConst, PointerDef, PointerFlags, PointerVTable,
5 PtrConst, PtrMut, PtrUninit, Shape, ShapeBuilder, Type, TypeParam, UserType, VTableIndirect,
6};
7
8unsafe fn nonnull_debug(
10 ox: OxPtrConst,
11 f: &mut core::fmt::Formatter<'_>,
12) -> Option<core::fmt::Result> {
13 let ptr = ox.ptr();
14 let inner_ptr = unsafe { *(ptr.as_byte_ptr() as *const *const u8) };
16 Some(write!(f, "{inner_ptr:p}"))
17}
18
19unsafe fn nonnull_hash(ox: OxPtrConst, hasher: &mut HashProxy<'_>) -> Option<()> {
21 use core::hash::Hasher;
22 let ptr = ox.ptr();
23 let inner_ptr = unsafe { *(ptr.as_byte_ptr() as *const *const u8) };
24 hasher.write_usize(inner_ptr as usize);
25 Some(())
26}
27
28unsafe fn nonnull_partial_eq(a: OxPtrConst, b: OxPtrConst) -> Option<bool> {
30 let a_ptr = a.ptr();
31 let b_ptr = b.ptr();
32 let a_inner = unsafe { *(a_ptr.as_byte_ptr() as *const *const u8) };
33 let b_inner = unsafe { *(b_ptr.as_byte_ptr() as *const *const u8) };
34 Some(a_inner == b_inner)
35}
36
37unsafe fn nonnull_partial_cmp(a: OxPtrConst, b: OxPtrConst) -> Option<Option<core::cmp::Ordering>> {
39 let a_ptr = a.ptr();
40 let b_ptr = b.ptr();
41 let a_inner = unsafe { *(a_ptr.as_byte_ptr() as *const *const u8) };
42 let b_inner = unsafe { *(b_ptr.as_byte_ptr() as *const *const u8) };
43 Some(a_inner.partial_cmp(&b_inner))
44}
45
46unsafe fn nonnull_cmp(a: OxPtrConst, b: OxPtrConst) -> Option<core::cmp::Ordering> {
48 let a_ptr = a.ptr();
49 let b_ptr = b.ptr();
50 let a_inner = unsafe { *(a_ptr.as_byte_ptr() as *const *const u8) };
51 let b_inner = unsafe { *(b_ptr.as_byte_ptr() as *const *const u8) };
52 Some(a_inner.cmp(&b_inner))
53}
54
55const NONNULL_VTABLE: VTableIndirect = VTableIndirect {
57 display: None,
58 debug: Some(nonnull_debug),
59 hash: Some(nonnull_hash),
60 invariants: None,
61 parse: None,
62 parse_bytes: None,
63 try_from: None,
64 try_into_inner: None,
65 try_borrow_inner: None,
66 partial_eq: Some(nonnull_partial_eq),
67 partial_cmp: Some(nonnull_partial_cmp),
68 cmp: Some(nonnull_cmp),
69};
70
71unsafe fn borrow_fn<'a, T: Facet<'a>>(this: PtrConst) -> PtrConst {
73 unsafe {
74 let ptr = this.get::<NonNull<T>>();
75 PtrConst::new(ptr.as_ptr())
76 }
77}
78
79unsafe fn new_into_fn<'a, 'ptr, T: Facet<'a>>(this: PtrUninit, ptr: PtrMut) -> PtrMut {
81 unsafe {
82 let raw_ptr = ptr.read::<*mut T>();
83 let non_null = core::ptr::NonNull::new_unchecked(raw_ptr);
84 this.put(non_null)
85 }
86}
87
88unsafe impl<'a, T: Facet<'a>> Facet<'a> for core::ptr::NonNull<T> {
89 const SHAPE: &'static Shape = &const {
90 ShapeBuilder::for_sized::<Self>("NonNull")
91 .ty(Type::User(UserType::Opaque))
92 .def(Def::Pointer(PointerDef {
93 vtable: &const {
94 PointerVTable {
95 borrow_fn: Some(borrow_fn::<T>),
96 new_into_fn: Some(new_into_fn::<T>),
97 ..PointerVTable::new()
98 }
99 },
100 pointee: Some(T::SHAPE),
101 weak: None,
102 strong: None,
103 flags: PointerFlags::EMPTY,
104 known: Some(KnownPointer::NonNull),
105 }))
106 .type_params(&[TypeParam {
107 name: "T",
108 shape: T::SHAPE,
109 }])
110 .vtable_indirect(&NONNULL_VTABLE)
111 .eq()
112 .copy()
113 .build()
114 };
115}