facet_reflect/partial/partial_api/
fields.rs1use super::*;
2
3impl<const BORROW: bool> Partial<'_, BORROW> {
7 pub fn field_index(&self, field_name: &str) -> Option<usize> {
12 let frame = self.frames().last()?;
13
14 match frame.shape.ty {
15 Type::User(UserType::Struct(struct_def)) => {
16 struct_def.fields.iter().position(|f| f.name == field_name)
17 }
18 Type::User(UserType::Enum(_)) => {
19 if let Tracker::Enum { variant, .. } = &frame.tracker {
21 variant
22 .data
23 .fields
24 .iter()
25 .position(|f| f.name == field_name)
26 } else {
27 None
28 }
29 }
30 _ => None,
31 }
32 }
33
34 pub fn is_field_set(&self, index: usize) -> Result<bool, ReflectError> {
36 let frame = self.frames().last().ok_or(ReflectError::NoActiveFrame)?;
37
38 match &frame.tracker {
39 Tracker::Scalar => Ok(frame.is_init),
40 Tracker::Struct { iset, .. } => Ok(iset.get(index)),
41 Tracker::Enum { data, variant, .. } => {
42 if data.get(index) {
44 return Ok(true);
45 }
46
47 if let Some(field) = variant.data.fields.get(index)
49 && let Type::User(UserType::Struct(field_struct)) = field.shape().ty
50 && field_struct.fields.is_empty()
51 {
52 return Ok(true);
53 }
54
55 Ok(false)
56 }
57 Tracker::Option { building_inner } => {
58 if index == 0 {
60 Ok(!building_inner)
61 } else {
62 Err(ReflectError::InvalidOperation {
63 operation: "is_field_set",
64 reason: "Option only has one field (index 0)",
65 })
66 }
67 }
68 Tracker::Result { building_inner, .. } => {
69 if index == 0 {
71 Ok(!building_inner)
72 } else {
73 Err(ReflectError::InvalidOperation {
74 operation: "is_field_set",
75 reason: "Result only has one field (index 0)",
76 })
77 }
78 }
79 _ => Err(ReflectError::InvalidOperation {
80 operation: "is_field_set",
81 reason: "Current frame is not a struct, enum variant, option, or result",
82 }),
83 }
84 }
85
86 pub fn begin_field(self, field_name: &str) -> Result<Self, ReflectError> {
91 let frame = self.frames().last().unwrap();
92 let fields = self.get_fields()?;
93 let Some(idx) = fields.iter().position(|f| f.name == field_name) else {
94 return Err(ReflectError::FieldError {
95 shape: frame.shape,
96 field_error: facet_core::FieldError::NoSuchField,
97 });
98 };
99 self.begin_nth_field(idx)
100 }
101
102 pub fn begin_nth_field(mut self, idx: usize) -> Result<Self, ReflectError> {
106 let field_name = self.get_field_name_for_path(idx);
111
112 if let FrameMode::Deferred {
114 stack,
115 start_depth,
116 current_path,
117 stored_frames,
118 ..
119 } = &mut self.mode
120 {
121 let relative_depth = stack.len() - *start_depth;
124 let should_track = current_path.len() == relative_depth;
125
126 if let Some(name) = field_name
127 && should_track
128 {
129 current_path.push(name);
130
131 if let Some(stored_frame) = stored_frames.remove(current_path) {
133 trace!("begin_nth_field: Restoring stored frame for path {current_path:?}");
134
135 let frame = stack.last_mut().unwrap();
137 frame.tracker.set_current_child(idx);
138
139 stack.push(stored_frame);
140 return Ok(self);
141 }
142 }
143 }
144
145 let frame = self.frames_mut().last_mut().unwrap();
146
147 let next_frame = match frame.shape.ty {
148 Type::User(user_type) => match user_type {
149 UserType::Struct(struct_type) => {
150 Self::begin_nth_struct_field(frame, struct_type, idx)?
151 }
152 UserType::Enum(_) => {
153 match &frame.tracker {
155 Tracker::Enum { variant, .. } => {
156 Self::begin_nth_enum_field(frame, variant, idx)?
157 }
158 _ => {
159 return Err(ReflectError::OperationFailed {
160 shape: frame.shape,
161 operation: "must call select_variant before selecting enum fields",
162 });
163 }
164 }
165 }
166 UserType::Union(_) => {
167 return Err(ReflectError::OperationFailed {
168 shape: frame.shape,
169 operation: "cannot select a field from a union",
170 });
171 }
172 UserType::Opaque => {
173 return Err(ReflectError::OperationFailed {
174 shape: frame.shape,
175 operation: "cannot select a field from an opaque type",
176 });
177 }
178 },
179 Type::Sequence(sequence_type) => match sequence_type {
180 SequenceType::Array(array_type) => {
181 Self::begin_nth_array_element(frame, array_type, idx)?
182 }
183 SequenceType::Slice(_) => {
184 return Err(ReflectError::OperationFailed {
185 shape: frame.shape,
186 operation: "cannot select a field from slices yet",
187 });
188 }
189 },
190 _ => {
191 return Err(ReflectError::OperationFailed {
192 shape: frame.shape,
193 operation: "cannot select a field from this type",
194 });
195 }
196 };
197
198 self.frames_mut().push(next_frame);
199 Ok(self)
200 }
201
202 fn get_field_name_for_path(&self, idx: usize) -> Option<&'static str> {
204 let frame = self.frames().last()?;
205 match frame.shape.ty {
206 Type::User(UserType::Struct(struct_type)) => {
207 struct_type.fields.get(idx).map(|f| f.name)
208 }
209 Type::User(UserType::Enum(_)) => {
210 if let Tracker::Enum { variant, .. } = &frame.tracker {
211 variant.data.fields.get(idx).map(|f| f.name)
212 } else {
213 None
214 }
215 }
216 _ => None,
218 }
219 }
220
221 pub fn set_nth_field_to_default(mut self, idx: usize) -> Result<Self, ReflectError> {
230 let frame = self.frames().last().unwrap();
231 let fields = self.get_fields()?;
232
233 if idx >= fields.len() {
234 return Err(ReflectError::OperationFailed {
235 shape: frame.shape,
236 operation: "field index out of bounds",
237 });
238 }
239
240 let field = fields[idx];
241
242 if let Some(default_source) = field.default {
244 self = self.begin_nth_field(idx)?;
245 match default_source {
246 facet_core::DefaultSource::Custom(field_default_fn) => {
247 self = unsafe {
249 self.set_from_function(|ptr| {
250 field_default_fn(ptr);
251 Ok(())
252 })?
253 };
254 }
255 facet_core::DefaultSource::FromTrait => {
256 self = self.set_default()?;
258 }
259 }
260 self.end()
261 } else if field.shape().is(Characteristic::Default) {
262 self = self.begin_nth_field(idx)?;
263 self = self.set_default()?;
264 self.end()
265 } else {
266 Err(ReflectError::DefaultAttrButNoDefaultImpl {
267 shape: field.shape(),
268 })
269 }
270 }
271}