facet_reflect/poke/
option.rs1use facet_core::{Facet, Opaque, OpaqueConst, OpaqueUninit, OptionDef, OptionVTable, Shape};
2
3use crate::Guard;
4
5pub struct PokeOptionUninit<'mem> {
7 data: OpaqueUninit<'mem>,
8 shape: &'static Shape,
9 def: OptionDef,
10}
11
12impl<'mem> PokeOptionUninit<'mem> {
13 pub(crate) unsafe fn new(
19 data: OpaqueUninit<'mem>,
20 shape: &'static Shape,
21 def: OptionDef,
22 ) -> Self {
23 Self { data, shape, def }
24 }
25
26 pub fn shape(&self) -> &'static Shape {
28 self.shape
29 }
30
31 pub fn def(&self) -> OptionDef {
33 self.def
34 }
35
36 pub fn vtable(&self) -> &'static OptionVTable {
38 self.def.vtable
39 }
40
41 #[inline(always)]
43 pub fn into_value(self) -> crate::PokeValueUninit<'mem> {
44 unsafe { crate::PokeValueUninit::new(self.data, self.shape) }
45 }
46
47 pub unsafe fn init_none(self) -> PokeOption<'mem> {
53 unsafe {
54 let inited = (self.vtable().init_none_fn)(self.data);
55 PokeOption::new(inited, self.shape, self.def)
56 }
57 }
58
59 pub unsafe fn write<'a>(self, value: facet_core::OpaqueConst<'a>) -> PokeOption<'mem> {
69 unsafe {
70 let inited = (self.vtable().init_some_fn)(self.data, value);
72 PokeOption::new(inited, self.shape, self.def)
73 }
74 }
75
76 pub unsafe fn put<T>(self, value: T) -> PokeOption<'mem> {
83 let value_opaque = facet_core::OpaqueConst::new(&raw const value);
84 let result = unsafe { self.write(value_opaque) };
85 core::mem::forget(value);
86 result
87 }
88}
89
90pub struct PokeOption<'mem> {
92 data: Opaque<'mem>,
93 shape: &'static Shape,
94 def: OptionDef,
95}
96
97impl<'mem> PokeOption<'mem> {
98 pub(crate) unsafe fn new(data: Opaque<'mem>, shape: &'static Shape, def: OptionDef) -> Self {
104 Self { data, shape, def }
105 }
106
107 pub fn shape(&self) -> &'static Shape {
109 self.shape
110 }
111
112 pub fn def(&self) -> OptionDef {
114 self.def
115 }
116
117 pub fn vtable(&self) -> &'static OptionVTable {
119 self.def.vtable
120 }
121
122 pub fn replace_with_none(self) -> Self {
124 unsafe { (self.vtable().replace_with_fn)(self.data, None) };
125 self
126 }
127
128 pub fn replace_with_some<T>(self, value: T) -> Self {
130 let value_opaque = OpaqueConst::new(&raw const value);
131 core::mem::forget(value);
132 self.replace_with_some_opaque(value_opaque)
133 }
134
135 pub fn replace_with_some_opaque(self, value: OpaqueConst<'mem>) -> Self {
137 unsafe { (self.vtable().replace_with_fn)(self.data, Some(value)) };
138 self
139 }
140
141 #[inline(always)]
143 pub fn into_value(self) -> crate::PokeValueUninit<'mem> {
144 unsafe {
145 crate::PokeValueUninit::new(OpaqueUninit::new(self.data.as_mut_byte_ptr()), self.shape)
146 }
147 }
148
149 #[inline]
151 pub fn build_in_place(self) -> Opaque<'mem> {
152 self.data
153 }
154
155 pub fn build<T: Facet>(self, guard: Option<Guard>) -> Option<T> {
163 let mut guard = guard;
164 let this = self;
165 this.shape.assert_type::<Option<T>>();
168 if let Some(guard) = &guard {
169 guard.shape.assert_type::<Option<T>>();
170 }
171
172 let result = unsafe {
173 let ptr = this.data.as_ref::<Option<T>>();
174 core::ptr::read(ptr)
175 };
176 guard.take(); result
178 }
179}