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

facet-rs / facet / 19778338603

29 Nov 2025 03:29AM UTC coverage: 60.95% (+0.02%) from 60.927%
19778338603

Pull #967

github

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

192 of 338 new or added lines in 3 files covered. (56.8%)

1 existing line in 1 file now uncovered.

18204 of 29867 relevant lines covered (60.95%)

157.73 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> {
106✔
14
        self.require_active()?;
106✔
15
        let frame = self.frames_mut().last_mut().unwrap();
106✔
16

17
        // Check tracker state before initializing
18
        match &frame.tracker {
89✔
19
            Tracker::Scalar if !frame.is_init => {
89✔
20
                // Good, will initialize below
89✔
21
            }
89✔
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 } => {
10✔
54
                // Already initialized as a dynamic object
55
                if matches!(state, DynamicValueState::Object { .. }) {
10✔
56
                    return Ok(self);
10✔
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 {
89✔
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) => {
19✔
86
                // Initialize as a dynamic object
19✔
87
                unsafe {
19✔
88
                    (dyn_def.vtable.begin_object)(frame.data);
19✔
89
                }
19✔
90

19✔
91
                // Update tracker to DynamicValue object state and mark as initialized
19✔
92
                frame.tracker = Tracker::DynamicValue {
19✔
93
                    state: DynamicValueState::Object {
19✔
94
                        insert_state: DynamicObjectInsertState::Idle,
19✔
95
                    },
19✔
96
                };
19✔
97
                frame.is_init = true;
19✔
98
            }
19✔
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)
89✔
108
    }
106✔
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> {
23✔
298
        crate::trace!("begin_object_entry({key:?})");
299
        self.require_active()?;
23✔
300
        let frame = self.frames_mut().last_mut().unwrap();
23✔
301

302
        // Check that we have a DynamicValue in Object state with Idle insert_state
303
        match (&frame.shape.def, &frame.tracker) {
23✔
304
            (
305
                Def::DynamicValue(_),
306
                Tracker::DynamicValue {
307
                    state:
308
                        DynamicValueState::Object {
309
                            insert_state: DynamicObjectInsertState::Idle,
310
                        },
311
                },
312
            ) if frame.is_init => {
23✔
313
                // Good, proceed
23✔
314
            }
23✔
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;
23✔
345
        let value_layout = match value_shape.layout.sized_layout() {
23✔
346
            Ok(layout) => layout,
23✔
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) };
23✔
356
        let Some(value_ptr) = NonNull::new(value_ptr) else {
23✔
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 {
23✔
365
            Tracker::DynamicValue {
366
                state: DynamicValueState::Object { insert_state },
23✔
367
            } => {
23✔
368
                *insert_state = DynamicObjectInsertState::BuildingValue {
23✔
369
                    key: String::from(key),
23✔
370
                };
23✔
371
            }
23✔
NEW
372
            _ => unreachable!(),
×
373
        }
374

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

382
        Ok(self)
23✔
383
    }
23✔
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