facet_core/impls_core/
smartptr.rs

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