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) = {
117 let frame = self.frames().last().unwrap();
118 if let Some(builder_shape) = frame.shape.builder_shape {
120 let has_try_from = frame.shape.vtable.has_try_from();
121 let is_option = matches!(frame.shape.def, Def::Option(_));
122 (Some(builder_shape), has_try_from, frame.shape, is_option)
123 } else if let Some(inner_shape) = frame.shape.inner {
124 let has_try_from = frame.shape.vtable.has_try_from();
125 let is_option = matches!(frame.shape.def, Def::Option(_));
126 (Some(inner_shape), has_try_from, frame.shape, is_option)
127 } else {
128 (None, false, frame.shape, false)
129 }
130 };
131
132 self.prepare_for_reinitialization();
134
135 if let Some(inner_shape) = inner_shape {
136 if has_try_from {
137 if is_option {
140 return self.begin_some();
141 }
142
143 let inner_layout =
149 inner_shape
150 .layout
151 .sized_layout()
152 .map_err(|_| ReflectError::Unsized {
153 shape: inner_shape,
154 operation: "begin_inner, getting inner layout",
155 })?;
156
157 let inner_data = if inner_layout.size() == 0 {
158 PtrUninit::new(NonNull::<u8>::dangling().as_ptr())
160 } else {
161 let ptr = unsafe { ::alloc::alloc::alloc(inner_layout) };
163 let Some(ptr) = NonNull::new(ptr) else {
164 ::alloc::alloc::handle_alloc_error(inner_layout);
165 };
166 PtrUninit::new(ptr.as_ptr())
167 };
168
169 trace!(
173 "begin_inner: Creating frame for inner type {inner_shape} (parent is {parent_shape})"
174 );
175 self.frames_mut()
176 .push(Frame::new(inner_data, inner_shape, FrameOwnership::Owned));
177
178 Ok(self)
179 } else {
180 trace!("begin_inner: No try_from for {parent_shape}, using field navigation");
183 self.begin_nth_field(0)
184 }
185 } else {
186 Err(ReflectError::OperationFailed {
187 shape: parent_shape,
188 operation: "type does not have an inner value",
189 })
190 }
191 }
192
193 pub fn begin_custom_deserialization(mut self) -> Result<Self, ReflectError> {
196 let current_frame = self.frames().last().unwrap();
197 let target_shape = current_frame.shape;
198 trace!("begin_custom_deserialization: target_shape={target_shape}");
199 if let Some(field) = self.parent_field() {
200 trace!("begin_custom_deserialization: field name={}", field.name);
201 if let Some(proxy_def) = field.proxy() {
202 let source_shape = proxy_def.shape;
204 let source_data = source_shape.allocate().map_err(|_| ReflectError::Unsized {
205 shape: target_shape,
206 operation: "Not a Sized type",
207 })?;
208
209 trace!(
210 "begin_custom_deserialization: Creating frame for deserialization type {source_shape}"
211 );
212 let mut new_frame = Frame::new(source_data, source_shape, FrameOwnership::Owned);
213 new_frame.using_custom_deserialization = true;
214 self.frames_mut().push(new_frame);
215
216 Ok(self)
217 } else {
218 Err(ReflectError::OperationFailed {
219 shape: target_shape,
220 operation: "field does not have a proxy definition",
221 })
222 }
223 } else {
224 Err(ReflectError::OperationFailed {
225 shape: target_shape,
226 operation: "not currently processing a field",
227 })
228 }
229 }
230
231 pub fn begin_custom_deserialization_from_shape(mut self) -> Result<(Self, bool), ReflectError> {
239 let current_frame = self.frames().last().unwrap();
240 let target_shape = current_frame.shape;
241 trace!("begin_custom_deserialization_from_shape: target_shape={target_shape}");
242
243 let Some(proxy_def) = target_shape.proxy else {
244 return Ok((self, false));
245 };
246
247 let source_shape = proxy_def.shape;
248 let source_data = source_shape.allocate().map_err(|_| ReflectError::Unsized {
249 shape: target_shape,
250 operation: "Not a Sized type",
251 })?;
252
253 trace!(
254 "begin_custom_deserialization_from_shape: Creating frame for deserialization type {source_shape}"
255 );
256 let mut new_frame = Frame::new(source_data, source_shape, FrameOwnership::Owned);
257 new_frame.using_custom_deserialization = true;
258 new_frame.shape_level_proxy = Some(proxy_def);
260 self.frames_mut().push(new_frame);
261
262 Ok((self, true))
263 }
264}