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

facet-rs / facet / 19774894729

28 Nov 2025 10:22PM UTC coverage: 59.711% (-0.6%) from 60.346%
19774894729

push

github

fasterthanlime
Add DynamicValue support for deserializing into facet_value::Value

This adds support for deserializing JSON (and potentially other formats)
into facet_value::Value without format crates needing to depend on facet-value.

Key changes:
- Add Def::DynamicValue variant with vtable for building dynamic values
- Implement Facet trait for Value in facet-value
- Extend Partial to handle DynamicValue scalars via set_into_dynamic_value
- Add deserialize_dynamic_value handler in facet-json

Currently supports scalar values (null, bool, numbers, strings).
Arrays and objects are stubbed out with TODO errors.

451 of 922 new or added lines in 20 files covered. (48.92%)

29 existing lines in 3 files now uncovered.

16657 of 27896 relevant lines covered (59.71%)

153.76 hits per line

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

56.15
/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
    pub fn begin_map(&mut self) -> Result<&mut Self, ReflectError> {
74✔
12
        self.require_active()?;
74✔
13
        let frame = self.frames_mut().last_mut().unwrap();
74✔
14

15
        // Check tracker state before initializing
16
        match &frame.tracker {
67✔
17
            Tracker::Scalar if !frame.is_init => {
67✔
18
                // Good, will initialize below
67✔
19
            }
67✔
20
            Tracker::Scalar => {
21
                // is_init is true - already initialized (from a previous round), just update tracker
22
                if !matches!(frame.shape.def, Def::Map(_)) {
×
23
                    return Err(ReflectError::OperationFailed {
×
24
                        shape: frame.shape,
×
25
                        operation: "begin_map can only be called on Map types",
×
26
                    });
×
27
                }
×
28
                frame.tracker = Tracker::Map {
×
29
                    insert_state: MapInsertState::Idle,
×
30
                };
×
31
                return Ok(self);
×
32
            }
33
            Tracker::Map { .. } => {
34
                if frame.is_init {
7✔
35
                    // Already initialized, nothing to do
36
                    return Ok(self);
7✔
37
                }
×
38
            }
39
            _ => {
40
                return Err(ReflectError::UnexpectedTracker {
×
NEW
41
                    message: "begin_map called but tracker isn't Scalar or Map",
×
42
                    current_tracker: frame.tracker.kind(),
×
43
                });
×
44
            }
45
        }
46

47
        // Check that we have a Map
48
        let map_def = match &frame.shape.def {
67✔
49
            Def::Map(map_def) => map_def,
67✔
50
            _ => {
51
                return Err(ReflectError::OperationFailed {
×
52
                    shape: frame.shape,
×
53
                    operation: "begin_map can only be called on Map types",
×
54
                });
×
55
            }
56
        };
57

58
        let init_fn = map_def.vtable.init_in_place_with_capacity_fn;
67✔
59

60
        // Initialize the map with default capacity (0)
61
        unsafe {
67✔
62
            init_fn(frame.data, 0);
67✔
63
        }
67✔
64

65
        // Update tracker to Map state and mark as initialized
66
        frame.tracker = Tracker::Map {
67✔
67
            insert_state: MapInsertState::Idle,
67✔
68
        };
67✔
69
        frame.is_init = true;
67✔
70

71
        Ok(self)
67✔
72
    }
74✔
73

74
    /// Pushes a frame for the map key. After that, `set()` should be called
75
    /// (or the key should be initialized somehow) and `end()` should be called
76
    /// to pop the frame.
77
    pub fn begin_key(&mut self) -> Result<&mut Self, ReflectError> {
97✔
78
        self.require_active()?;
97✔
79
        let frame = self.frames_mut().last_mut().unwrap();
97✔
80

81
        // Check that we have a Map in Idle state
82
        let map_def = match (&frame.shape.def, &frame.tracker) {
97✔
83
            (
84
                Def::Map(map_def),
97✔
85
                Tracker::Map {
86
                    insert_state: MapInsertState::Idle,
87
                },
88
            ) if frame.is_init => map_def,
97✔
89
            (
90
                Def::Map(_),
91
                Tracker::Map {
92
                    insert_state: MapInsertState::PushingKey { .. },
93
                },
94
            ) => {
95
                return Err(ReflectError::OperationFailed {
×
96
                    shape: frame.shape,
×
97
                    operation: "already pushing a key, call end() first",
×
98
                });
×
99
            }
100
            (
101
                Def::Map(_),
102
                Tracker::Map {
103
                    insert_state: MapInsertState::PushingValue { .. },
104
                },
105
            ) => {
106
                return Err(ReflectError::OperationFailed {
×
107
                    shape: frame.shape,
×
108
                    operation: "must complete current operation before begin_key()",
×
109
                });
×
110
            }
111
            _ => {
112
                return Err(ReflectError::OperationFailed {
×
113
                    shape: frame.shape,
×
114
                    operation: "must call begin_map() before begin_key()",
×
115
                });
×
116
            }
117
        };
118

119
        // Get the key shape
120
        let key_shape = map_def.k();
97✔
121

122
        // Allocate space for the key
123
        let key_layout = match key_shape.layout.sized_layout() {
97✔
124
            Ok(layout) => layout,
97✔
125
            Err(_) => {
126
                return Err(ReflectError::Unsized {
×
127
                    shape: key_shape,
×
128
                    operation: "begin_key allocating key",
×
129
                });
×
130
            }
131
        };
132
        let key_ptr_raw: *mut u8 = unsafe { ::alloc::alloc::alloc(key_layout) };
97✔
133

134
        let Some(key_ptr_raw) = NonNull::new(key_ptr_raw) else {
97✔
135
            return Err(ReflectError::OperationFailed {
×
136
                shape: frame.shape,
×
137
                operation: "failed to allocate memory for map key",
×
138
            });
×
139
        };
140

141
        let key_ptr = PtrUninit::new(key_ptr_raw);
97✔
142

143
        // Store the key pointer in the insert state
144
        match &mut frame.tracker {
97✔
145
            Tracker::Map { insert_state, .. } => {
97✔
146
                *insert_state = MapInsertState::PushingKey {
97✔
147
                    key_ptr,
97✔
148
                    key_initialized: false,
97✔
149
                };
97✔
150
            }
97✔
151
            _ => unreachable!(),
×
152
        }
153

154
        // Push a new frame for the key
155
        self.frames_mut().push(Frame::new(
97✔
156
            PtrUninit::new(key_ptr_raw),
97✔
157
            key_shape,
97✔
158
            FrameOwnership::ManagedElsewhere, // Ownership tracked in MapInsertState
97✔
159
        ));
160

161
        Ok(self)
97✔
162
    }
97✔
163

164
    /// Pushes a frame for the map value
165
    /// Must be called after the key has been set and popped
166
    pub fn begin_value(&mut self) -> Result<&mut Self, ReflectError> {
92✔
167
        self.require_active()?;
92✔
168
        let frame = self.frames_mut().last_mut().unwrap();
92✔
169

170
        // Check that we have a Map in PushingValue state with no value_ptr yet
171
        let (map_def, key_ptr) = match (&frame.shape.def, &frame.tracker) {
92✔
172
            (
173
                Def::Map(map_def),
92✔
174
                Tracker::Map {
175
                    insert_state:
176
                        MapInsertState::PushingValue {
177
                            value_ptr: None,
178
                            key_ptr,
92✔
179
                            ..
180
                        },
181
                    ..
182
                },
183
            ) => (map_def, *key_ptr),
92✔
184
            (
185
                Def::Map(_),
186
                Tracker::Map {
187
                    insert_state:
188
                        MapInsertState::PushingValue {
189
                            value_ptr: Some(_), ..
190
                        },
191
                    ..
192
                },
193
            ) => {
194
                return Err(ReflectError::OperationFailed {
×
195
                    shape: frame.shape,
×
196
                    operation: "already pushing a value, call end() first",
×
197
                });
×
198
            }
199
            _ => {
200
                return Err(ReflectError::OperationFailed {
×
201
                    shape: frame.shape,
×
202
                    operation: "must complete key before begin_value()",
×
203
                });
×
204
            }
205
        };
206

207
        // Get the value shape
208
        let value_shape = map_def.v();
92✔
209

210
        // Allocate space for the value
211
        let value_layout = match value_shape.layout.sized_layout() {
92✔
212
            Ok(layout) => layout,
92✔
213
            Err(_) => {
214
                return Err(ReflectError::Unsized {
×
215
                    shape: value_shape,
×
216
                    operation: "begin_value allocating value",
×
217
                });
×
218
            }
219
        };
220
        let value_ptr_raw: *mut u8 = unsafe { ::alloc::alloc::alloc(value_layout) };
92✔
221

222
        let Some(value_ptr_raw) = NonNull::new(value_ptr_raw) else {
92✔
223
            return Err(ReflectError::OperationFailed {
×
224
                shape: frame.shape,
×
225
                operation: "failed to allocate memory for map value",
×
226
            });
×
227
        };
228

229
        let value_ptr = PtrUninit::new(value_ptr_raw);
92✔
230

231
        // Store the value pointer in the insert state
232
        match &mut frame.tracker {
92✔
233
            Tracker::Map { insert_state, .. } => {
92✔
234
                *insert_state = MapInsertState::PushingValue {
92✔
235
                    key_ptr,
92✔
236
                    value_ptr: Some(value_ptr),
92✔
237
                    value_initialized: false,
92✔
238
                };
92✔
239
            }
92✔
240
            _ => unreachable!(),
×
241
        }
242

243
        // Push a new frame for the value
244
        self.frames_mut().push(Frame::new(
92✔
245
            value_ptr,
92✔
246
            value_shape,
92✔
247
            FrameOwnership::ManagedElsewhere, // Ownership tracked in MapInsertState
92✔
248
        ));
249

250
        Ok(self)
92✔
251
    }
92✔
252
}
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