facet_core/impls_core/
nonnull.rs

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