facet_core/impls_core/
nonnull.rs

1use crate::{
2    Def, Facet, Field, FieldFlags, KnownPointer, PointerDef, PointerFlags, PointerVTable, PtrConst,
3    Repr, StructKind, StructType, Type, UserType, ValueVTable, value_vtable,
4};
5
6unsafe impl<'a, T: Facet<'a>> Facet<'a> for core::ptr::NonNull<T> {
7    const VTABLE: &'static ValueVTable = &const {
8        value_vtable!(core::ptr::NonNull<T>, |f, _opts| write!(
9            f,
10            "{}",
11            Self::SHAPE.type_identifier
12        ))
13    };
14
15    const SHAPE: &'static crate::Shape = &const {
16        crate::Shape::builder_for_sized::<Self>()
17            .type_identifier("NonNull")
18            .type_params(&[crate::TypeParam {
19                name: "T",
20                shape: || T::SHAPE,
21            }])
22            .ty(Type::User(UserType::Struct(StructType {
23                repr: Repr::transparent(),
24                kind: StructKind::Struct,
25                fields: &const {
26                    [Field::builder()
27                        .name("pointer")
28                        .shape(<*mut T>::SHAPE)
29                        .offset(0)
30                        .flags(FieldFlags::EMPTY)
31                        .build()]
32                },
33            })))
34            .def(Def::Pointer(
35                PointerDef::builder()
36                    .pointee(|| T::SHAPE)
37                    .flags(PointerFlags::EMPTY)
38                    .known(KnownPointer::NonNull)
39                    .vtable(
40                        &const {
41                            PointerVTable::builder()
42                                .borrow_fn(|this| {
43                                    let ptr = unsafe { this.get::<Self>().as_ptr() };
44                                    PtrConst::new(ptr).into()
45                                })
46                                .new_into_fn(|this, ptr| {
47                                    let ptr = unsafe { ptr.read::<*mut T>() };
48                                    let non_null =
49                                        unsafe { core::ptr::NonNull::new_unchecked(ptr) };
50                                    unsafe { this.put(non_null) }
51                                })
52                                .build()
53                        },
54                    )
55                    .build(),
56            ))
57            .build()
58    };
59}