facet_reflect/partial/typed.rs
1use alloc::{boxed::Box, string::String};
2
3use crate::{Partial, Peek, ReflectError, trace};
4use core::marker::PhantomData;
5use facet_core::{Facet, PtrConst, PtrUninit, Shape, Variant};
6
7/// A typed wrapper around `Partial`, for when you want to statically
8/// ensure that `build` gives you the proper type.
9pub struct TypedPartial<'facet, T: ?Sized> {
10 pub(crate) inner: Partial<'facet>,
11 pub(crate) phantom: PhantomData<T>,
12}
13
14impl<'facet, T> TypedPartial<'facet, T> {
15 /// Borrows the inner [Partial] mutably
16 pub fn inner_mut(&mut self) -> &mut Partial<'facet> {
17 &mut self.inner
18 }
19}
20
21////////////////////////////////////////////////////////////////////////////////////////////////////
22// Misc.
23////////////////////////////////////////////////////////////////////////////////////////////////////
24impl<'facet, T: ?Sized> TypedPartial<'facet, T> {
25 /// Returns the current frame count (depth of nesting)
26 ///
27 /// The initial frame count is 1 — `begin_field` would push a new frame,
28 /// bringing it to 2, then `end` would bring it back to `1`.
29 ///
30 /// This is an implementation detail of `Partial`, kinda, but deserializers
31 /// might use this for debug assertions, to make sure the state is what
32 /// they think it is.
33 #[inline]
34 pub fn frame_count(&self) -> usize {
35 self.inner.frame_count()
36 }
37
38 /// Returns the shape of the current frame.
39 #[inline]
40 pub fn shape(&self) -> &'static Shape {
41 self.inner.shape()
42 }
43
44 /// Pops the current frame off the stack, indicating we're done initializing the current field
45 #[inline]
46 pub fn end(&mut self) -> Result<&mut Self, ReflectError> {
47 self.inner.end()?;
48 Ok(self)
49 }
50
51 /// Returns a human-readable path representing the current traversal in the builder,
52 /// e.g., `RootStruct.fieldName[index].subfield`.
53 pub fn path(&self) -> String {
54 self.inner.path()
55 }
56}
57
58////////////////////////////////////////////////////////////////////////////////////////////////////
59// Build
60////////////////////////////////////////////////////////////////////////////////////////////////////
61impl<'facet, T> TypedPartial<'facet, T> {
62 /// Builds the value and returns a `Box<T>`
63 pub fn build(&mut self) -> Result<Box<T>, ReflectError>
64 where
65 T: Facet<'facet>,
66 {
67 self.inner.require_active()?;
68
69 trace!(
70 "TypedPartial::build: Building value for type {} which should == {}",
71 T::SHAPE,
72 self.inner.shape()
73 );
74 let heap_value = self.inner.build()?;
75 trace!(
76 "TypedPartial::build: Built heap value with shape: {}",
77 heap_value.shape()
78 );
79 // Safety: HeapValue was constructed from T and the shape layout is correct.
80 let result = unsafe { heap_value.into_box_unchecked::<T>() };
81 trace!("TypedPartial::build: Successfully converted to Box<T>");
82 Ok(result)
83 }
84}
85
86////////////////////////////////////////////////////////////////////////////////////////////////////
87// `Set` and set helpers
88////////////////////////////////////////////////////////////////////////////////////////////////////
89impl<'facet, T: ?Sized> TypedPartial<'facet, T> {
90 /// Sets a value wholesale into the current frame.
91 ///
92 /// If the current frame was already initialized, the previous value is
93 /// dropped. If it was partially initialized, the fields that were initialized
94 /// are dropped, etc.
95 #[inline]
96 pub fn set<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
97 where
98 U: Facet<'facet>,
99 {
100 self.inner.set(value)?;
101 Ok(self)
102 }
103
104 /// Sets a value into the current frame by shape, for shape-based operations
105 ///
106 /// If this returns Ok, then `src_value` has been moved out of
107 ///
108 /// # Safety
109 ///
110 /// The caller must ensure that `src_value` points to a valid instance of a value
111 /// whose memory layout and type matches `src_shape`, and that this value can be
112 /// safely copied (bitwise) into the destination specified by the Partial's current frame.
113 /// No automatic drop will be performed for any existing value, so calling this on an
114 /// already-initialized destination may result in leaks or double drops if misused.
115 /// After a successful call, the ownership of the value at `src_value` is effectively moved
116 /// into the Partial (i.e., the destination), and the original value should not be used
117 /// or dropped by the caller; consider using `core::mem::forget` on the passed value.
118 /// If an error is returned, the destination remains unmodified and safe for future operations.
119 #[inline]
120 pub unsafe fn set_shape(
121 &mut self,
122 src_value: PtrConst<'_>,
123 src_shape: &'static Shape,
124 ) -> Result<&mut Self, ReflectError> {
125 unsafe { self.inner.set_shape(src_value, src_shape)? };
126 Ok(self)
127 }
128
129 /// Sets the current frame using a function that initializes the value
130 ///
131 /// # Safety
132 ///
133 /// If `f` returns Ok(), it is assumed that it initialized the passed pointer fully and with a
134 /// value of the right type.
135 ///
136 /// If `f` returns Err(), it is assumed that it did NOT initialize the passed pointer and that
137 /// there is no need to drop it in place.
138 #[inline]
139 pub unsafe fn set_from_function<F>(&mut self, f: F) -> Result<&mut Self, ReflectError>
140 where
141 F: FnOnce(PtrUninit<'_>) -> Result<(), ReflectError>,
142 {
143 unsafe {
144 self.inner.set_from_function(f)?;
145 }
146 Ok(self)
147 }
148
149 /// Sets the current frame to its default value using `default_in_place` from the
150 /// vtable.
151 ///
152 /// Note: if you have `struct S { field: F }`, and `F` does not implement `Default`
153 /// but `S` does, this doesn't magically uses S's `Default` implementation to get a value
154 /// for `field`.
155 ///
156 /// If the current frame's shape does not implement `Default`, then this returns an error.
157 #[inline]
158 pub fn set_default(&mut self) -> Result<&mut Self, ReflectError> {
159 self.inner.set_default()?;
160 Ok(self)
161 }
162
163 /// Copy a value from a Peek into the current frame.
164 ///
165 /// # Invariants
166 ///
167 /// `peek` must be a thin pointer, otherwise this panics.
168 ///
169 /// # Safety
170 ///
171 /// If this succeeds, the value `Peek` points to has been moved out of, and
172 /// as such, should not be dropped (but should be deallocated).
173 pub unsafe fn set_from_peek(&mut self, peek: &Peek<'_, '_>) -> Result<&mut Self, ReflectError> {
174 unsafe {
175 self.inner.set_from_peek(peek)?;
176 }
177 Ok(self)
178 }
179
180 /// Parses a string value into the current frame using the type's ParseFn from the vtable.
181 ///
182 /// If the current frame was previously initialized, its contents are dropped in place.
183 #[inline]
184 pub fn parse_from_str(&mut self, s: &str) -> Result<&mut Self, ReflectError> {
185 self.inner.parse_from_str(s)?;
186 Ok(self)
187 }
188}
189
190////////////////////////////////////////////////////////////////////////////////////////////////////
191// Enum variant selection
192////////////////////////////////////////////////////////////////////////////////////////////////////
193impl<'facet, T: ?Sized> TypedPartial<'facet, T> {
194 /// Get the currently selected variant for an enum
195 #[inline]
196 pub fn selected_variant(&self) -> Option<Variant> {
197 self.inner.selected_variant()
198 }
199
200 /// Find a variant by name in the current enum
201 #[inline]
202 pub fn find_variant(&self, variant_name: &str) -> Option<(usize, &'static Variant)> {
203 self.inner.find_variant(variant_name)
204 }
205
206 /// Assuming the current frame is an enum, this selects a variant by index
207 /// (0-based, in declaration order).
208 ///
209 /// For example:
210 ///
211 /// ```rust,no_run
212 /// enum E { A, B, C }
213 /// ```
214 ///
215 /// Calling `select_nth_variant(2)` would select variant `C`.
216 ///
217 /// This will return an error if the current frame is anything other than fully-uninitialized.
218 /// In other words, it's not possible to "switch to a different variant" once you've selected one.
219 ///
220 /// This does _not_ push a frame on the stack.
221 #[inline]
222 pub fn select_nth_variant(&mut self, index: usize) -> Result<&mut Self, ReflectError> {
223 self.inner.select_nth_variant(index)?;
224 Ok(self)
225 }
226
227 /// Pushes a variant for enum initialization by name
228 ///
229 /// See [Self::select_nth_variant] for more notes.
230 #[inline]
231 pub fn select_variant_named(&mut self, variant_name: &str) -> Result<&mut Self, ReflectError> {
232 self.inner.select_variant_named(variant_name)?;
233 Ok(self)
234 }
235
236 /// Selects a given enum variant by discriminant. If none of the variants
237 /// of the frame's enum have that discriminant, this returns an error.
238 ///
239 /// See [Self::select_nth_variant] for more notes.
240 #[inline]
241 pub fn select_variant(&mut self, discriminant: i64) -> Result<&mut Self, ReflectError> {
242 self.inner.select_variant(discriminant)?;
243 Ok(self)
244 }
245}
246
247////////////////////////////////////////////////////////////////////////////////////////////////////
248// Field selection
249////////////////////////////////////////////////////////////////////////////////////////////////////
250impl<'facet, T: ?Sized> TypedPartial<'facet, T> {
251 /// Find the index of a field by name in the current struct
252 ///
253 /// If the current frame isn't a struct or an enum (with a selected variant)
254 /// then this returns `None` for sure.
255 #[inline]
256 pub fn field_index(&self, field_name: &str) -> Option<usize> {
257 self.inner.field_index(field_name)
258 }
259
260 /// Check if a struct field at the given index has been set
261 #[inline]
262 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
263 self.inner.is_field_set(index)
264 }
265
266 /// Selects a field (by name) of a struct or enum data.
267 ///
268 /// For enums, the variant needs to be selected first, see [Self::select_nth_variant]
269 /// and friends.
270 #[inline]
271 pub fn begin_field(&mut self, field_name: &str) -> Result<&mut Self, ReflectError> {
272 self.inner.begin_field(field_name)?;
273 Ok(self)
274 }
275
276 /// Begins the nth field of a struct, enum variant, or array, by index.
277 ///
278 /// On success, this pushes a new frame which must be ended with a call to [Partial::end]
279 #[inline]
280 pub fn begin_nth_field(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
281 self.inner.begin_nth_field(idx)?;
282 Ok(self)
283 }
284
285 /// Sets the given field to its default value, preferring:
286 ///
287 /// * A `default = some_fn()` function
288 /// * The field's `Default` implementation if any
289 ///
290 /// But without going all the way up to the parent struct's `Default` impl.
291 ///
292 /// Errors out if idx is out of bound, if the field has no default method or Default impl.
293 #[inline]
294 pub fn set_nth_field_to_default(&mut self, idx: usize) -> Result<&mut Self, ReflectError> {
295 self.inner.set_nth_field_to_default(idx)?;
296 Ok(self)
297 }
298
299 /// Given a `Partial` for the same shape, and assuming that partial has the nth
300 /// field initialized, move the value from `src` to `self`, marking it as deinitialized
301 /// in `src`.
302 #[inline]
303 pub fn steal_nth_field(
304 &mut self,
305 src: &mut TypedPartial<T>,
306 field_index: usize,
307 ) -> Result<&mut Self, ReflectError> {
308 self.inner.steal_nth_field(&mut src.inner, field_index)?;
309 Ok(self)
310 }
311
312 /// For a field that supports custom deserialization via the `deserialize_with` attribute begin
313 /// the process of constructing the shape to be used as input to the `deserialize_with` method.
314 /// Calling end after constructing the shape will pass it to the `deserialize_with` associated method
315 /// and store the result in the frame's pointer.
316 #[inline]
317 pub fn begin_custom_deserialization(&mut self) -> Result<&mut Self, ReflectError> {
318 self.inner.begin_custom_deserialization()?;
319 Ok(self)
320 }
321}
322
323////////////////////////////////////////////////////////////////////////////////////////////////////
324// Smart pointers
325////////////////////////////////////////////////////////////////////////////////////////////////////
326impl<'facet, T: ?Sized> TypedPartial<'facet, T> {
327 /// Pushes a frame to initialize the inner value of a smart pointer (`Box<T>`, `Arc<T>`, etc.)
328 #[inline]
329 pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError> {
330 self.inner.begin_smart_ptr()?;
331 Ok(self)
332 }
333}
334
335////////////////////////////////////////////////////////////////////////////////////////////////////
336// Lists
337////////////////////////////////////////////////////////////////////////////////////////////////////
338impl<'facet, T: ?Sized> TypedPartial<'facet, T> {
339 /// Initializes a list (Vec, etc.) if it hasn't been initialized before.
340 /// This is a prerequisite to `begin_push_item`/`set`/`end` or the shorthand
341 /// `push`.
342 ///
343 /// `begin_list` does not clear the list if it was previously initialized.
344 /// `begin_list` does not push a new frame to the stack, and thus does not
345 /// require `end` to be called afterwards.
346 #[inline]
347 pub fn begin_list(&mut self) -> Result<&mut Self, ReflectError> {
348 self.inner.begin_list()?;
349 Ok(self)
350 }
351
352 /// Pushes an element to the list
353 /// The element should be set using `set()` or similar methods, then `pop()` to complete
354 #[inline]
355 pub fn begin_list_item(&mut self) -> Result<&mut Self, ReflectError> {
356 self.inner.begin_list_item()?;
357 Ok(self)
358 }
359}
360
361////////////////////////////////////////////////////////////////////////////////////////////////////
362// Maps
363////////////////////////////////////////////////////////////////////////////////////////////////////
364impl<'facet, T: ?Sized> TypedPartial<'facet, T> {
365 /// Begins a map initialization operation
366 ///
367 /// This initializes the map with default capacity and allows inserting key-value pairs
368 /// It does _not_ push a new frame onto the stack.
369 #[inline]
370 pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
371 self.inner.begin_map()?;
372 Ok(self)
373 }
374
375 /// Pushes a frame for the map key. After that, `set()` should be called
376 /// (or the key should be initialized somehow) and `end()` should be called
377 /// to pop the frame.
378 #[inline]
379 pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
380 self.inner.begin_key()?;
381 Ok(self)
382 }
383
384 /// Pushes a frame for the map value
385 /// Must be called after the key has been set and popped
386 #[inline]
387 pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
388 self.inner.begin_value()?;
389 Ok(self)
390 }
391}
392
393////////////////////////////////////////////////////////////////////////////////////////////////////
394// Option / inner
395////////////////////////////////////////////////////////////////////////////////////////////////////
396impl<'facet, T: ?Sized> TypedPartial<'facet, T> {
397 /// Begin building the `Some` variant of an `Option`
398 #[inline]
399 pub fn begin_some(&mut self) -> Result<&mut Self, ReflectError> {
400 self.inner.begin_some()?;
401 Ok(self)
402 }
403
404 /// Begin building the inner value of a wrapper type
405 #[inline]
406 pub fn begin_inner(&mut self) -> Result<&mut Self, ReflectError> {
407 self.inner.begin_inner()?;
408 Ok(self)
409 }
410}
411
412////////////////////////////////////////////////////////////////////////////////////////////////////
413// Shorthands
414////////////////////////////////////////////////////////////////////////////////////////////////////
415impl<'facet, T: ?Sized> TypedPartial<'facet, T> {
416 /// Convenience shortcut: sets the field at index `idx` directly to value, popping after.
417 #[inline]
418 pub fn set_nth_field<U>(&mut self, idx: usize, value: U) -> Result<&mut Self, ReflectError>
419 where
420 U: Facet<'facet>,
421 {
422 self.inner.set_nth_field(idx, value)?;
423 Ok(self)
424 }
425
426 /// Convenience shortcut: sets the named field to value, popping after.
427 #[inline]
428 pub fn set_field<U>(&mut self, field_name: &str, value: U) -> Result<&mut Self, ReflectError>
429 where
430 U: Facet<'facet>,
431 {
432 self.inner.set_field(field_name, value)?;
433 Ok(self)
434 }
435
436 /// Convenience shortcut: sets the key for a map key-value insertion, then pops after.
437 #[inline]
438 pub fn set_key<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
439 where
440 U: Facet<'facet>,
441 {
442 self.inner.set_key(value)?;
443 Ok(self)
444 }
445
446 /// Convenience shortcut: sets the value for a map key-value insertion, then pops after.
447 #[inline]
448 pub fn set_value<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
449 where
450 U: Facet<'facet>,
451 {
452 self.inner.set_value(value)?;
453 Ok(self)
454 }
455
456 /// Shorthand for: begin_list_item(), set(), end(), useful when pushing a scalar
457 #[inline]
458 pub fn push<U>(&mut self, value: U) -> Result<&mut Self, ReflectError>
459 where
460 U: Facet<'facet>,
461 {
462 self.inner.push(value)?;
463 Ok(self)
464 }
465}
466
467impl<'facet, T> core::fmt::Debug for TypedPartial<'facet, T> {
468 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
469 f.debug_struct("TypedPartial")
470 .field("shape", &self.inner.frames.last().map(|frame| frame.shape))
471 .finish()
472 }
473}