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