facet_reflect/partial/partial_api/
alloc.rs

1use super::*;
2
3////////////////////////////////////////////////////////////////////////////////////////////////////
4// Allocation, constructors etc.
5////////////////////////////////////////////////////////////////////////////////////////////////////
6
7/// Allocate a Partial that can borrow from input with lifetime 'facet.
8/// This is the default mode - use this when deserializing from a buffer that outlives the result.
9impl<'facet> Partial<'facet, true> {
10    /// Allocates a new [Partial] instance on the heap, with the given shape and type.
11    ///
12    /// This creates a borrowing Partial that can hold references with lifetime 'facet.
13    pub fn alloc<T>() -> Result<Self, ReflectError>
14    where
15        T: Facet<'facet> + ?Sized,
16    {
17        Self::alloc_shape(T::SHAPE)
18    }
19
20    /// Allocates a new [Partial] instance on the heap, with the given shape.
21    ///
22    /// This creates a borrowing Partial that can hold references with lifetime 'facet.
23    pub fn alloc_shape(shape: &'static Shape) -> Result<Self, ReflectError> {
24        alloc_shape_inner(shape)
25    }
26}
27
28/// Allocate a Partial that cannot borrow - all data must be owned.
29/// Use this when deserializing from a temporary buffer (e.g., HTTP request body).
30impl Partial<'static, false> {
31    /// Allocates a new [Partial] instance on the heap, with the given shape and type.
32    ///
33    /// This creates an owned Partial that cannot hold borrowed references.
34    /// Use this when the input buffer is temporary and won't outlive the result.
35    pub fn alloc_owned<T>() -> Result<Self, ReflectError>
36    where
37        T: Facet<'static> + ?Sized,
38    {
39        Self::alloc_shape_owned(T::SHAPE)
40    }
41
42    /// Allocates a new [Partial] instance on the heap, with the given shape.
43    ///
44    /// This creates an owned Partial that cannot hold borrowed references.
45    pub fn alloc_shape_owned(shape: &'static Shape) -> Result<Self, ReflectError> {
46        alloc_shape_inner(shape)
47    }
48}
49
50fn alloc_shape_inner<'facet, const BORROW: bool>(
51    shape: &'static Shape,
52) -> Result<Partial<'facet, BORROW>, ReflectError> {
53    crate::trace!(
54        "alloc_shape({:?}), with layout {:?}",
55        shape,
56        shape.layout.sized_layout()
57    );
58
59    let data = shape.allocate().map_err(|_| ReflectError::Unsized {
60        shape,
61        operation: "alloc_shape",
62    })?;
63
64    // Preallocate a couple of frames. The cost of allocating 4 frames is
65    // basically identical to allocating 1 frame, so for every type that
66    // has at least 1 level of nesting, this saves at least one guaranteed reallocation.
67    let mut stack = Vec::with_capacity(4);
68    stack.push(Frame::new(data, shape, FrameOwnership::Owned));
69
70    Ok(Partial {
71        mode: FrameMode::Strict { stack },
72        state: PartialState::Active,
73        invariant: PhantomData,
74    })
75}