facet_reflect/partial/partial_api/
option.rs1use super::*;
2
3impl<const BORROW: bool> Partial<'_, BORROW> {
7 pub fn begin_some(mut self) -> Result<Self, ReflectError> {
9 let option_def = {
11 let frame = self.frames().last().unwrap();
12 match frame.shape.def {
13 Def::Option(def) => def,
14 _ => {
15 return Err(ReflectError::WasNotA {
16 expected: "Option",
17 actual: frame.shape,
18 });
19 }
20 }
21 };
22
23 let needs_reinit = {
27 let frame = self.frames().last().unwrap();
28 frame.is_init
29 || matches!(
30 frame.tracker,
31 Tracker::Option {
32 building_inner: false
33 }
34 )
35 };
36
37 if needs_reinit {
38 self.prepare_for_reinitialization();
39 }
40
41 if let FrameMode::Deferred {
45 stack,
46 start_depth,
47 current_path,
48 stored_frames,
49 ..
50 } = &mut self.mode
51 {
52 let relative_depth = stack.len() - *start_depth;
53 let should_track = current_path.len() == relative_depth;
54
55 if should_track {
56 current_path.push("Some");
57
58 if let Some(stored_frame) = stored_frames.remove(current_path) {
60 trace!("begin_some: Restoring stored frame for path {current_path:?}");
61
62 let frame = stack.last_mut().unwrap();
64 frame.tracker = Tracker::Option {
65 building_inner: true,
66 };
67
68 stack.push(stored_frame);
69 return Ok(self);
70 }
71 }
72 }
73
74 let frame = self.frames_mut().last_mut().unwrap();
76 frame.tracker = Tracker::Option {
77 building_inner: true,
78 };
79
80 let inner_shape = option_def.t;
82
83 let inner_layout =
85 inner_shape
86 .layout
87 .sized_layout()
88 .map_err(|_| ReflectError::Unsized {
89 shape: inner_shape,
90 operation: "begin_some, allocating Option inner value",
91 })?;
92
93 let inner_data = if inner_layout.size() == 0 {
94 PtrUninit::new(NonNull::<u8>::dangling().as_ptr())
96 } else {
97 let ptr = unsafe { ::alloc::alloc::alloc(inner_layout) };
99 let Some(ptr) = NonNull::new(ptr) else {
100 ::alloc::alloc::handle_alloc_error(inner_layout);
101 };
102 PtrUninit::new(ptr.as_ptr())
103 };
104
105 let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
107 self.frames_mut().push(inner_frame);
108
109 Ok(self)
110 }
111
112 pub fn begin_inner(mut self) -> Result<Self, ReflectError> {
114 let (inner_shape, has_try_from, parent_shape, is_option) = {
116 let frame = self.frames().last().unwrap();
117 if let Some(inner_shape) = frame.shape.inner {
118 let has_try_from = frame.shape.vtable.has_try_from();
119 let is_option = matches!(frame.shape.def, Def::Option(_));
120 (Some(inner_shape), has_try_from, frame.shape, is_option)
121 } else {
122 (None, false, frame.shape, false)
123 }
124 };
125
126 self.prepare_for_reinitialization();
128
129 if let Some(inner_shape) = inner_shape {
130 if has_try_from {
131 if is_option {
134 return self.begin_some();
135 }
136
137 let inner_layout =
143 inner_shape
144 .layout
145 .sized_layout()
146 .map_err(|_| ReflectError::Unsized {
147 shape: inner_shape,
148 operation: "begin_inner, getting inner layout",
149 })?;
150
151 let inner_data = if inner_layout.size() == 0 {
152 PtrUninit::new(NonNull::<u8>::dangling().as_ptr())
154 } else {
155 let ptr = unsafe { ::alloc::alloc::alloc(inner_layout) };
157 let Some(ptr) = NonNull::new(ptr) else {
158 ::alloc::alloc::handle_alloc_error(inner_layout);
159 };
160 PtrUninit::new(ptr.as_ptr())
161 };
162
163 trace!(
167 "begin_inner: Creating frame for inner type {inner_shape} (parent is {parent_shape})"
168 );
169 self.frames_mut()
170 .push(Frame::new(inner_data, inner_shape, FrameOwnership::Owned));
171
172 Ok(self)
173 } else {
174 trace!("begin_inner: No try_from for {parent_shape}, using field navigation");
177 self.begin_nth_field(0)
178 }
179 } else {
180 Err(ReflectError::OperationFailed {
181 shape: parent_shape,
182 operation: "type does not have an inner value",
183 })
184 }
185 }
186
187 pub fn begin_custom_deserialization(mut self) -> Result<Self, ReflectError> {
190 let current_frame = self.frames().last().unwrap();
191 let target_shape = current_frame.shape;
192 trace!("begin_custom_deserialization: target_shape={target_shape}");
193 if let Some(field) = self.parent_field() {
194 trace!("begin_custom_deserialization: field name={}", field.name);
195 if let Some(proxy_def) = field.proxy() {
196 let source_shape = proxy_def.shape;
198 let source_data = source_shape.allocate().map_err(|_| ReflectError::Unsized {
199 shape: target_shape,
200 operation: "Not a Sized type",
201 })?;
202
203 trace!(
204 "begin_custom_deserialization: Creating frame for deserialization type {source_shape}"
205 );
206 let mut new_frame = Frame::new(source_data, source_shape, FrameOwnership::Owned);
207 new_frame.using_custom_deserialization = true;
208 self.frames_mut().push(new_frame);
209
210 Ok(self)
211 } else {
212 Err(ReflectError::OperationFailed {
213 shape: target_shape,
214 operation: "field does not have a proxy definition",
215 })
216 }
217 } else {
218 Err(ReflectError::OperationFailed {
219 shape: target_shape,
220 operation: "not currently processing a field",
221 })
222 }
223 }
224
225 pub fn begin_custom_deserialization_from_shape(mut self) -> Result<(Self, bool), ReflectError> {
233 let current_frame = self.frames().last().unwrap();
234 let target_shape = current_frame.shape;
235 trace!("begin_custom_deserialization_from_shape: target_shape={target_shape}");
236
237 let Some(proxy_def) = target_shape.proxy else {
238 return Ok((self, false));
239 };
240
241 let source_shape = proxy_def.shape;
242 let source_data = source_shape.allocate().map_err(|_| ReflectError::Unsized {
243 shape: target_shape,
244 operation: "Not a Sized type",
245 })?;
246
247 trace!(
248 "begin_custom_deserialization_from_shape: Creating frame for deserialization type {source_shape}"
249 );
250 let mut new_frame = Frame::new(source_data, source_shape, FrameOwnership::Owned);
251 new_frame.using_custom_deserialization = true;
252 new_frame.shape_level_proxy = Some(proxy_def);
254 self.frames_mut().push(new_frame);
255
256 Ok((self, true))
257 }
258}