facet_reflect/partial/partial_api/
sets.rs1use super::*;
2use crate::AllocatedShape;
3
4impl<const BORROW: bool> Partial<'_, BORROW> {
8 pub fn init_set(mut self) -> Result<Self, ReflectError> {
15 crate::trace!("init_set()");
16 let shape = self.frames().last().unwrap().allocated.shape();
18 let frame = self.frames_mut().last_mut().unwrap();
19
20 match &frame.tracker {
21 Tracker::Scalar if !frame.is_init => {
22 }
24 Tracker::Scalar => {
25 frame.tracker = Tracker::Set {
27 current_child: false,
28 };
29 return Ok(self);
30 }
31 Tracker::Set { .. } => {
32 if frame.is_init {
33 return Ok(self);
35 }
36 }
37 _ => {
38 let tracker_kind = frame.tracker.kind();
39 return Err(self.err(ReflectErrorKind::UnexpectedTracker {
40 message: "init_set called but tracker isn't something set-like",
41 current_tracker: tracker_kind,
42 }));
43 }
44 };
45
46 let set_def = match &shape.def {
48 Def::Set(set_def) => set_def,
49 _ => {
50 return Err(self.err(ReflectErrorKind::OperationFailed {
51 shape,
52 operation: "init_set can only be called on Set types",
53 }));
54 }
55 };
56
57 let init_fn = set_def.vtable.init_in_place_with_capacity;
58
59 unsafe {
61 init_fn(frame.data, 0);
62 }
63
64 frame.tracker = Tracker::Set {
66 current_child: false,
67 };
68 frame.is_init = true;
69
70 Ok(self)
71 }
72
73 pub fn begin_set_item(mut self) -> Result<Self, ReflectError> {
76 crate::trace!("begin_set_item()");
77 let (shape, parent_type_plan, set_def, is_init, has_current_child) = {
79 let frame = self.frames().last().unwrap();
80 let shape = frame.allocated.shape();
81 let set_def = match &shape.def {
82 Def::Set(set_def) => *set_def,
83 _ => {
84 return Err(self.err(ReflectErrorKind::OperationFailed {
85 shape,
86 operation: "init_set_item can only be called on Set types",
87 }));
88 }
89 };
90 let has_current_child = match &frame.tracker {
91 Tracker::Set { current_child } => *current_child,
92 _ => {
93 return Err(self.err(ReflectErrorKind::OperationFailed {
94 shape,
95 operation: "must call init_set() before begin_set_item()",
96 }));
97 }
98 };
99 (
100 shape,
101 frame.type_plan,
102 set_def,
103 frame.is_init,
104 has_current_child,
105 )
106 };
107
108 if !is_init {
110 return Err(self.err(ReflectErrorKind::OperationFailed {
111 shape,
112 operation: "must call init_set() before begin_set_item()",
113 }));
114 }
115 if has_current_child {
116 return Err(self.err(ReflectErrorKind::OperationFailed {
117 shape,
118 operation: "already pushing an element, call end() first",
119 }));
120 }
121
122 match &mut self.mode.stack_mut().last_mut().unwrap().tracker {
124 Tracker::Set { current_child } => *current_child = true,
125 _ => unreachable!(),
126 }
127
128 let element_shape = set_def.t();
130
131 let element_layout = match element_shape.layout.sized_layout() {
133 Ok(layout) => layout,
134 Err(_) => {
135 return Err(self.err(ReflectErrorKind::Unsized {
136 shape: element_shape,
137 operation: "begin_set_item: calculating element layout",
138 }));
139 }
140 };
141 let element_ptr = facet_core::alloc_for_layout(element_layout);
142
143 let child_plan_id = self
146 .root_plan
147 .set_item_node_id(parent_type_plan)
148 .expect("TypePlan should have item node for Set");
149 self.mode.stack_mut().push(Frame::new(
150 element_ptr,
151 AllocatedShape::new(element_shape, element_layout.size()),
152 FrameOwnership::Owned,
153 child_plan_id,
154 ));
155
156 Ok(self)
157 }
158}