facet_core/impls_core/
smartptr.rs

1use core::alloc::Layout;
2
3use crate::{
4    ConstTypeId, Def, Facet, KnownSmartPointer, PtrConst, SmartPointerDef, SmartPointerFlags,
5    SmartPointerVTable, value_vtable,
6};
7
8unsafe impl<T: Facet> Facet for core::ptr::NonNull<T> {
9    const SHAPE: &'static crate::Shape = &const {
10        crate::Shape::builder()
11            .id(ConstTypeId::of::<Self>())
12            .layout(Layout::new::<Self>())
13            .type_params(&[crate::TypeParam {
14                name: "T",
15                shape: || T::SHAPE,
16            }])
17            .def(Def::SmartPointer(
18                SmartPointerDef::builder()
19                    .pointee(T::SHAPE)
20                    .flags(SmartPointerFlags::EMPTY)
21                    .known(KnownSmartPointer::NonNull)
22                    .vtable(
23                        &const {
24                            SmartPointerVTable::builder()
25                                .borrow_fn(|opaque| {
26                                    let ptr = unsafe { opaque.get::<Self>().as_ptr() };
27                                    PtrConst::new(ptr)
28                                })
29                                .new_into_fn(|this, ptr| {
30                                    let ptr = unsafe { ptr.read::<*mut T>() };
31                                    let non_null =
32                                        unsafe { core::ptr::NonNull::new_unchecked(ptr) };
33                                    unsafe { this.put(non_null) }
34                                })
35                                .build()
36                        },
37                    )
38                    .build(),
39            ))
40            .vtable(value_vtable!(core::ptr::NonNull<T>, |f, _opts| write!(
41                f,
42                "NonNull"
43            )))
44            .build()
45    };
46}