facet_core/impls_alloc/
smartptr.rs

1use core::alloc::Layout;
2
3use crate::{
4    ConstTypeId, Def, Facet, KnownSmartPointer, Opaque, PtrConst, SmartPointerDef,
5    SmartPointerFlags, SmartPointerVTable, value_vtable,
6};
7
8unsafe impl<T: Facet> Facet for alloc::sync::Arc<T> {
9    const SHAPE: &'static crate::Shape = &const {
10        crate::Shape::builder()
11            .id(ConstTypeId::of::<Self>())
12            .layout(Layout::new::<Self>())
13            .def(Def::SmartPointer(
14                SmartPointerDef::builder()
15                    .pointee(T::SHAPE)
16                    .flags(SmartPointerFlags::ATOMIC)
17                    .known(KnownSmartPointer::Arc)
18                    .weak(|| <alloc::sync::Weak<T> as Facet>::SHAPE)
19                    .vtable(
20                        &const {
21                            SmartPointerVTable::builder()
22                                .borrow_fn(|opaque| {
23                                    let ptr = Self::as_ptr(unsafe { opaque.get() });
24                                    PtrConst::new(ptr)
25                                })
26                                .new_into_fn(|this, ptr| {
27                                    let t = unsafe { ptr.read::<T>() };
28                                    let arc = alloc::sync::Arc::new(t);
29                                    unsafe { this.put(arc) }
30                                })
31                                .downgrade_fn(|strong, weak| unsafe {
32                                    weak.put(alloc::sync::Arc::downgrade(strong.get::<Self>()))
33                                })
34                                .build()
35                        },
36                    )
37                    .build(),
38            ))
39            .vtable(value_vtable!(alloc::sync::Arc<T>, |f, _opts| write!(
40                f,
41                "Arc"
42            )))
43            .build()
44    };
45}
46
47unsafe impl<T: Facet> Facet for alloc::sync::Weak<T> {
48    const SHAPE: &'static crate::Shape = &const {
49        crate::Shape::builder()
50            .id(ConstTypeId::of::<Self>())
51            .layout(Layout::new::<Self>())
52            .def(Def::SmartPointer(
53                SmartPointerDef::builder()
54                    .pointee(T::SHAPE)
55                    .flags(SmartPointerFlags::ATOMIC.union(SmartPointerFlags::WEAK))
56                    .known(KnownSmartPointer::ArcWeak)
57                    .strong(|| <alloc::sync::Arc<T> as Facet>::SHAPE)
58                    .vtable(
59                        &const {
60                            SmartPointerVTable::builder()
61                                .upgrade_into_fn(|weak, strong| unsafe {
62                                    Some(strong.put(weak.get::<Self>().upgrade()?))
63                                })
64                                .build()
65                        },
66                    )
67                    .build(),
68            ))
69            .vtable(value_vtable!(alloc::sync::Arc<T>, |f, _opts| write!(
70                f,
71                "Arc"
72            )))
73            .build()
74    };
75}
76
77unsafe impl<T> Facet for Opaque<alloc::sync::Arc<T>> {
78    const SHAPE: &'static crate::Shape = &const {
79        crate::Shape::builder()
80            .id(ConstTypeId::of::<Self>())
81            .layout(Layout::new::<Self>())
82            .def(Def::SmartPointer(
83                SmartPointerDef::builder()
84                    .flags(SmartPointerFlags::ATOMIC)
85                    .known(KnownSmartPointer::Arc)
86                    .vtable(
87                        &const {
88                            SmartPointerVTable::builder()
89                                .borrow_fn(|opaque| {
90                                    let ptr =
91                                        alloc::sync::Arc::<T>::as_ptr(unsafe { opaque.get() });
92                                    PtrConst::new(ptr)
93                                })
94                                .new_into_fn(|this, ptr| {
95                                    let t = unsafe { ptr.read::<T>() };
96                                    let arc = alloc::sync::Arc::new(t);
97                                    unsafe { this.put(arc) }
98                                })
99                                .build()
100                        },
101                    )
102                    .build(),
103            ))
104            .vtable(value_vtable!(alloc::sync::Arc<T>, |f, _opts| write!(
105                f,
106                "Arc"
107            )))
108            .build()
109    };
110}