• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

facet-rs / facet / 19778276897

29 Nov 2025 03:24AM UTC coverage: 60.911% (-0.02%) from 60.927%
19778276897

Pull #967

github

web-flow
Merge 1b6645e5f into a7f5cbcf6
Pull Request #967: Add TOML → facet_value::Value deserialization support

164 of 312 new or added lines in 3 files covered. (52.56%)

1 existing line in 1 file now uncovered.

18177 of 29842 relevant lines covered (60.91%)

157.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.44
/facet-reflect/src/partial/partial_api/maps.rs
1
use super::*;
2

3
////////////////////////////////////////////////////////////////////////////////////////////////////
4
// Maps
5
////////////////////////////////////////////////////////////////////////////////////////////////////
6
impl Partial<'_> {
7
    /// Begins a map initialization operation
8
    ///
9
    /// This initializes the map with default capacity and allows inserting key-value pairs
10
    /// It does _not_ push a new frame onto the stack.
11
    ///
12
    /// For `Def::DynamicValue` types, this initializes as an object instead of a map.
13
    pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
93✔
14
        self.require_active()?;
93✔
15
        let frame = self.frames_mut().last_mut().unwrap();
93✔
16

17
        // Check tracker state before initializing
18
        match &frame.tracker {
84✔
19
            Tracker::Scalar if !frame.is_init => {
84✔
20
                // Good, will initialize below
84✔
21
            }
84✔
22
            Tracker::Scalar => {
23
                // is_init is true - already initialized (from a previous round), just update tracker
NEW
24
                match frame.shape.def {
×
25
                    Def::Map(_) => {
NEW
26
                        frame.tracker = Tracker::Map {
×
NEW
27
                            insert_state: MapInsertState::Idle,
×
NEW
28
                        };
×
NEW
29
                        return Ok(self);
×
30
                    }
31
                    Def::DynamicValue(_) => {
NEW
32
                        frame.tracker = Tracker::DynamicValue {
×
NEW
33
                            state: DynamicValueState::Object {
×
NEW
34
                                insert_state: DynamicObjectInsertState::Idle,
×
NEW
35
                            },
×
NEW
36
                        };
×
NEW
37
                        return Ok(self);
×
38
                    }
39
                    _ => {
NEW
40
                        return Err(ReflectError::OperationFailed {
×
NEW
41
                            shape: frame.shape,
×
NEW
42
                            operation: "begin_map can only be called on Map or DynamicValue types",
×
NEW
43
                        });
×
44
                    }
45
                }
46
            }
47
            Tracker::Map { .. } => {
48
                if frame.is_init {
7✔
49
                    // Already initialized, nothing to do
50
                    return Ok(self);
7✔
51
                }
×
52
            }
53
            Tracker::DynamicValue { state } => {
2✔
54
                // Already initialized as a dynamic object
55
                if matches!(state, DynamicValueState::Object { .. }) {
2✔
56
                    return Ok(self);
2✔
NEW
57
                }
×
58
                // Otherwise (Scalar or Array state), we need to deinit before reinitializing
NEW
59
                frame.deinit();
×
60
            }
61
            _ => {
62
                return Err(ReflectError::UnexpectedTracker {
×
NEW
63
                    message: "begin_map called but tracker isn't Scalar, Map, or DynamicValue",
×
64
                    current_tracker: frame.tracker.kind(),
×
65
                });
×
66
            }
67
        }
68

69
        // Check that we have a Map or DynamicValue
70
        match &frame.shape.def {
84✔
71
            Def::Map(map_def) => {
70✔
72
                let init_fn = map_def.vtable.init_in_place_with_capacity_fn;
70✔
73

70✔
74
                // Initialize the map with default capacity (0)
70✔
75
                unsafe {
70✔
76
                    init_fn(frame.data, 0);
70✔
77
                }
70✔
78

70✔
79
                // Update tracker to Map state and mark as initialized
70✔
80
                frame.tracker = Tracker::Map {
70✔
81
                    insert_state: MapInsertState::Idle,
70✔
82
                };
70✔
83
                frame.is_init = true;
70✔
84
            }
70✔
85
            Def::DynamicValue(dyn_def) => {
14✔
86
                // Initialize as a dynamic object
14✔
87
                unsafe {
14✔
88
                    (dyn_def.vtable.begin_object)(frame.data);
14✔
89
                }
14✔
90

14✔
91
                // Update tracker to DynamicValue object state and mark as initialized
14✔
92
                frame.tracker = Tracker::DynamicValue {
14✔
93
                    state: DynamicValueState::Object {
14✔
94
                        insert_state: DynamicObjectInsertState::Idle,
14✔
95
                    },
14✔
96
                };
14✔
97
                frame.is_init = true;
14✔
98
            }
14✔
99
            _ => {
100
                return Err(ReflectError::OperationFailed {
×
101
                    shape: frame.shape,
×
NEW
102
                    operation: "begin_map can only be called on Map or DynamicValue types",
×
103
                });
×
104
            }
105
        }
106

107
        Ok(self)
84✔
108
    }
93✔
109

110
    /// Pushes a frame for the map key. After that, `set()` should be called
111
    /// (or the key should be initialized somehow) and `end()` should be called
112
    /// to pop the frame.
113
    pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
105✔
114
        self.require_active()?;
105✔
115
        let frame = self.frames_mut().last_mut().unwrap();
105✔
116

117
        // Check that we have a Map in Idle state
118
        let map_def = match (&frame.shape.def, &frame.tracker) {
105✔
119
            (
120
                Def::Map(map_def),
104✔
121
                Tracker::Map {
122
                    insert_state: MapInsertState::Idle,
123
                },
124
            ) if frame.is_init => map_def,
104✔
125
            (
126
                Def::Map(_),
127
                Tracker::Map {
128
                    insert_state: MapInsertState::PushingKey { .. },
129
                },
130
            ) => {
131
                return Err(ReflectError::OperationFailed {
×
132
                    shape: frame.shape,
×
133
                    operation: "already pushing a key, call end() first",
×
134
                });
×
135
            }
136
            (
137
                Def::Map(_),
138
                Tracker::Map {
139
                    insert_state: MapInsertState::PushingValue { .. },
140
                },
141
            ) => {
142
                return Err(ReflectError::OperationFailed {
×
143
                    shape: frame.shape,
×
144
                    operation: "must complete current operation before begin_key()",
×
145
                });
×
146
            }
147
            _ => {
148
                return Err(ReflectError::OperationFailed {
1✔
149
                    shape: frame.shape,
1✔
150
                    operation: "must call begin_map() before begin_key()",
1✔
151
                });
1✔
152
            }
153
        };
154

155
        // Get the key shape
156
        let key_shape = map_def.k();
104✔
157

158
        // Allocate space for the key
159
        let key_layout = match key_shape.layout.sized_layout() {
104✔
160
            Ok(layout) => layout,
104✔
161
            Err(_) => {
162
                return Err(ReflectError::Unsized {
×
163
                    shape: key_shape,
×
164
                    operation: "begin_key allocating key",
×
165
                });
×
166
            }
167
        };
168
        let key_ptr_raw: *mut u8 = unsafe { ::alloc::alloc::alloc(key_layout) };
104✔
169

170
        let Some(key_ptr_raw) = NonNull::new(key_ptr_raw) else {
104✔
171
            return Err(ReflectError::OperationFailed {
×
172
                shape: frame.shape,
×
173
                operation: "failed to allocate memory for map key",
×
174
            });
×
175
        };
176

177
        let key_ptr = PtrUninit::new(key_ptr_raw);
104✔
178

179
        // Store the key pointer in the insert state
180
        match &mut frame.tracker {
104✔
181
            Tracker::Map { insert_state, .. } => {
104✔
182
                *insert_state = MapInsertState::PushingKey {
104✔
183
                    key_ptr,
104✔
184
                    key_initialized: false,
104✔
185
                };
104✔
186
            }
104✔
187
            _ => unreachable!(),
×
188
        }
189

190
        // Push a new frame for the key
191
        self.frames_mut().push(Frame::new(
104✔
192
            PtrUninit::new(key_ptr_raw),
104✔
193
            key_shape,
104✔
194
            FrameOwnership::ManagedElsewhere, // Ownership tracked in MapInsertState
104✔
195
        ));
196

197
        Ok(self)
104✔
198
    }
105✔
199

200
    /// Pushes a frame for the map value
201
    /// Must be called after the key has been set and popped
202
    pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
118✔
203
        self.require_active()?;
118✔
204
        let frame = self.frames_mut().last_mut().unwrap();
117✔
205

206
        // Check that we have a Map in PushingValue state with no value_ptr yet
207
        let (map_def, key_ptr) = match (&frame.shape.def, &frame.tracker) {
117✔
208
            (
209
                Def::Map(map_def),
99✔
210
                Tracker::Map {
211
                    insert_state:
212
                        MapInsertState::PushingValue {
213
                            value_ptr: None,
214
                            key_ptr,
99✔
215
                            ..
216
                        },
217
                    ..
218
                },
219
            ) => (map_def, *key_ptr),
99✔
220
            (
221
                Def::Map(_),
222
                Tracker::Map {
223
                    insert_state:
224
                        MapInsertState::PushingValue {
225
                            value_ptr: Some(_), ..
226
                        },
227
                    ..
228
                },
229
            ) => {
230
                return Err(ReflectError::OperationFailed {
×
231
                    shape: frame.shape,
×
232
                    operation: "already pushing a value, call end() first",
×
233
                });
×
234
            }
235
            _ => {
236
                return Err(ReflectError::OperationFailed {
18✔
237
                    shape: frame.shape,
18✔
238
                    operation: "must complete key before begin_value()",
18✔
239
                });
18✔
240
            }
241
        };
242

243
        // Get the value shape
244
        let value_shape = map_def.v();
99✔
245

246
        // Allocate space for the value
247
        let value_layout = match value_shape.layout.sized_layout() {
99✔
248
            Ok(layout) => layout,
99✔
249
            Err(_) => {
250
                return Err(ReflectError::Unsized {
×
251
                    shape: value_shape,
×
252
                    operation: "begin_value allocating value",
×
253
                });
×
254
            }
255
        };
256
        let value_ptr_raw: *mut u8 = unsafe { ::alloc::alloc::alloc(value_layout) };
99✔
257

258
        let Some(value_ptr_raw) = NonNull::new(value_ptr_raw) else {
99✔
259
            return Err(ReflectError::OperationFailed {
×
260
                shape: frame.shape,
×
261
                operation: "failed to allocate memory for map value",
×
262
            });
×
263
        };
264

265
        let value_ptr = PtrUninit::new(value_ptr_raw);
99✔
266

267
        // Store the value pointer in the insert state
268
        match &mut frame.tracker {
99✔
269
            Tracker::Map { insert_state, .. } => {
99✔
270
                *insert_state = MapInsertState::PushingValue {
99✔
271
                    key_ptr,
99✔
272
                    value_ptr: Some(value_ptr),
99✔
273
                    value_initialized: false,
99✔
274
                };
99✔
275
            }
99✔
276
            _ => unreachable!(),
×
277
        }
278

279
        // Push a new frame for the value
280
        self.frames_mut().push(Frame::new(
99✔
281
            value_ptr,
99✔
282
            value_shape,
99✔
283
            FrameOwnership::ManagedElsewhere, // Ownership tracked in MapInsertState
99✔
284
        ));
285

286
        Ok(self)
99✔
287
    }
118✔
288

289
    /// Begins an object entry for a DynamicValue object.
290
    ///
291
    /// This is a simpler API than begin_key/begin_value for DynamicValue objects,
292
    /// where keys are always strings. The key is stored and a frame is pushed for
293
    /// the value. After setting the value and calling `end()`, the key-value pair
294
    /// will be inserted into the object.
295
    ///
296
    /// For `Def::Map` types, use `begin_key()` / `begin_value()` instead.
297
    pub fn begin_object_entry(&mut self, key: &str) -> Result<&mut Self, ReflectError> {
17✔
298
        crate::trace!("begin_object_entry({key:?})");
299
        self.require_active()?;
17✔
300
        let frame = self.frames_mut().last_mut().unwrap();
17✔
301

302
        // Check that we have a DynamicValue in Object state with Idle insert_state
303
        match (&frame.shape.def, &frame.tracker) {
17✔
304
            (
305
                Def::DynamicValue(_),
306
                Tracker::DynamicValue {
307
                    state:
308
                        DynamicValueState::Object {
309
                            insert_state: DynamicObjectInsertState::Idle,
310
                        },
311
                },
312
            ) if frame.is_init => {
17✔
313
                // Good, proceed
17✔
314
            }
17✔
315
            (
316
                Def::DynamicValue(_),
317
                Tracker::DynamicValue {
318
                    state:
319
                        DynamicValueState::Object {
320
                            insert_state: DynamicObjectInsertState::BuildingValue { .. },
321
                        },
322
                },
323
            ) => {
NEW
324
                return Err(ReflectError::OperationFailed {
×
NEW
325
                    shape: frame.shape,
×
NEW
326
                    operation: "already building a value, call end() first",
×
NEW
327
                });
×
328
            }
329
            (Def::DynamicValue(_), _) => {
NEW
330
                return Err(ReflectError::OperationFailed {
×
NEW
331
                    shape: frame.shape,
×
NEW
332
                    operation: "must call begin_map() before begin_object_entry()",
×
NEW
333
                });
×
334
            }
335
            _ => {
NEW
336
                return Err(ReflectError::OperationFailed {
×
NEW
337
                    shape: frame.shape,
×
NEW
338
                    operation: "begin_object_entry can only be called on DynamicValue types",
×
NEW
339
                });
×
340
            }
341
        }
342

343
        // For DynamicValue objects, the value shape is the same DynamicValue shape
344
        let value_shape = frame.shape;
17✔
345
        let value_layout = match value_shape.layout.sized_layout() {
17✔
346
            Ok(layout) => layout,
17✔
347
            Err(_) => {
NEW
348
                return Err(ReflectError::Unsized {
×
NEW
349
                    shape: value_shape,
×
NEW
350
                    operation: "begin_object_entry: calculating value layout",
×
NEW
351
                });
×
352
            }
353
        };
354

355
        let value_ptr: *mut u8 = unsafe { ::alloc::alloc::alloc(value_layout) };
17✔
356
        let Some(value_ptr) = NonNull::new(value_ptr) else {
17✔
NEW
357
            return Err(ReflectError::OperationFailed {
×
NEW
358
                shape: frame.shape,
×
NEW
359
                operation: "failed to allocate memory for object value",
×
NEW
360
            });
×
361
        };
362

363
        // Update the insert state with the key
364
        match &mut frame.tracker {
17✔
365
            Tracker::DynamicValue {
366
                state: DynamicValueState::Object { insert_state },
17✔
367
            } => {
17✔
368
                *insert_state = DynamicObjectInsertState::BuildingValue {
17✔
369
                    key: String::from(key),
17✔
370
                };
17✔
371
            }
17✔
NEW
372
            _ => unreachable!(),
×
373
        }
374

375
        // Push a new frame for the value
376
        self.frames_mut().push(Frame::new(
17✔
377
            PtrUninit::new(value_ptr),
17✔
378
            value_shape,
17✔
379
            FrameOwnership::Owned,
17✔
380
        ));
381

382
        Ok(self)
17✔
383
    }
17✔
384
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc