facet_reflect/partial/partial_api/
result.rs

1use super::*;
2
3////////////////////////////////////////////////////////////////////////////////////////////////////
4// Result
5////////////////////////////////////////////////////////////////////////////////////////////////////
6impl<const BORROW: bool> Partial<'_, BORROW> {
7    /// Begin building the Ok variant of a Result
8    pub fn begin_ok(mut self) -> Result<Self, ReflectError> {
9        // Verify we're working with a Result and get the def
10        let result_def = {
11            let frame = self.frames().last().unwrap();
12            match frame.shape.def {
13                Def::Result(def) => def,
14                _ => {
15                    return Err(ReflectError::WasNotA {
16                        expected: "Result",
17                        actual: frame.shape,
18                    });
19                }
20            }
21        };
22
23        // Check if we need to handle re-initialization.
24        let needs_reinit = {
25            let frame = self.frames().last().unwrap();
26            frame.is_init
27                || matches!(
28                    frame.tracker,
29                    Tracker::Result {
30                        building_inner: false,
31                        ..
32                    }
33                )
34        };
35
36        if needs_reinit {
37            self.prepare_for_reinitialization();
38        }
39
40        // Set tracker to indicate we're building the Ok value
41        let frame = self.frames_mut().last_mut().unwrap();
42        frame.tracker = Tracker::Result {
43            is_ok: true,
44            building_inner: true,
45        };
46
47        // Get the Ok type shape
48        let inner_shape = result_def.t;
49
50        // Allocate memory for the inner value
51        let inner_layout =
52            inner_shape
53                .layout
54                .sized_layout()
55                .map_err(|_| ReflectError::Unsized {
56                    shape: inner_shape,
57                    operation: "begin_ok, allocating Result Ok value",
58                })?;
59
60        let inner_data = if inner_layout.size() == 0 {
61            // For ZST, use a non-null but unallocated pointer
62            PtrUninit::new(NonNull::<u8>::dangling().as_ptr())
63        } else {
64            // Allocate memory for the inner value
65            let ptr = unsafe { ::alloc::alloc::alloc(inner_layout) };
66            let Some(ptr) = NonNull::new(ptr) else {
67                ::alloc::alloc::handle_alloc_error(inner_layout);
68            };
69            PtrUninit::new(ptr.as_ptr())
70        };
71
72        // Create a new frame for the inner value
73        let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
74        self.frames_mut().push(inner_frame);
75
76        Ok(self)
77    }
78
79    /// Begin building the Err variant of a Result
80    pub fn begin_err(mut self) -> Result<Self, ReflectError> {
81        // Verify we're working with a Result and get the def
82        let result_def = {
83            let frame = self.frames().last().unwrap();
84            match frame.shape.def {
85                Def::Result(def) => def,
86                _ => {
87                    return Err(ReflectError::WasNotA {
88                        expected: "Result",
89                        actual: frame.shape,
90                    });
91                }
92            }
93        };
94
95        // Check if we need to handle re-initialization.
96        let needs_reinit = {
97            let frame = self.frames().last().unwrap();
98            frame.is_init
99                || matches!(
100                    frame.tracker,
101                    Tracker::Result {
102                        building_inner: false,
103                        ..
104                    }
105                )
106        };
107
108        if needs_reinit {
109            self.prepare_for_reinitialization();
110        }
111
112        // Set tracker to indicate we're building the Err value
113        let frame = self.frames_mut().last_mut().unwrap();
114        frame.tracker = Tracker::Result {
115            is_ok: false,
116            building_inner: true,
117        };
118
119        // Get the Err type shape
120        let inner_shape = result_def.e;
121
122        // Allocate memory for the inner value
123        let inner_layout =
124            inner_shape
125                .layout
126                .sized_layout()
127                .map_err(|_| ReflectError::Unsized {
128                    shape: inner_shape,
129                    operation: "begin_err, allocating Result Err value",
130                })?;
131
132        let inner_data = if inner_layout.size() == 0 {
133            // For ZST, use a non-null but unallocated pointer
134            PtrUninit::new(NonNull::<u8>::dangling().as_ptr())
135        } else {
136            // Allocate memory for the inner value
137            let ptr = unsafe { ::alloc::alloc::alloc(inner_layout) };
138            let Some(ptr) = NonNull::new(ptr) else {
139                ::alloc::alloc::handle_alloc_error(inner_layout);
140            };
141            PtrUninit::new(ptr.as_ptr())
142        };
143
144        // Create a new frame for the inner value
145        let inner_frame = Frame::new(inner_data, inner_shape, FrameOwnership::Owned);
146        self.frames_mut().push(inner_frame);
147
148        Ok(self)
149    }
150}