• 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

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

3
////////////////////////////////////////////////////////////////////////////////////////////////////
4
// Smart pointers
5
////////////////////////////////////////////////////////////////////////////////////////////////////
6
impl Partial<'_> {
7
    /// Pushes a frame to initialize the inner value of a smart pointer (`Box<T>`, `Arc<T>`, etc.)
8
    pub fn begin_smart_ptr(&mut self) -> Result<&mut Self, ReflectError> {
50✔
9
        crate::trace!("begin_smart_ptr()");
10
        self.require_active()?;
50✔
11

12
        // Check that we have a SmartPointer and get necessary data
13
        let (smart_ptr_def, pointee_shape) = {
50✔
14
            let frame = self.frames().last().unwrap();
50✔
15

16
            match &frame.shape.def {
50✔
17
                Def::Pointer(smart_ptr_def) if smart_ptr_def.constructible_from_pointee() => {
50✔
18
                    let pointee_shape = match smart_ptr_def.pointee() {
50✔
19
                        Some(shape) => shape,
50✔
20
                        None => {
NEW
21
                            return Err(ReflectError::OperationFailed {
×
NEW
22
                                shape: frame.shape,
×
NEW
23
                                operation: "Smart pointer must have a pointee shape",
×
UNCOV
24
                            });
×
25
                        }
26
                    };
27
                    (*smart_ptr_def, pointee_shape)
50✔
28
                }
29
                _ => {
NEW
30
                    return Err(ReflectError::OperationFailed {
×
NEW
31
                        shape: frame.shape,
×
NEW
32
                        operation: "push_smart_ptr can only be called on compatible types",
×
NEW
33
                    });
×
34
                }
35
            }
36
        };
37

38
        // Handle re-initialization if the smart pointer is already initialized
39
        self.prepare_for_reinitialization();
50✔
40

41
        let frame = self.frames_mut().last_mut().unwrap();
50✔
42

43
        if pointee_shape.layout.sized_layout().is_ok() {
50✔
44
            // pointee is sized, we can allocate it — for `Arc<T>` we'll be allocating a `T` and
45
            // holding onto it. We'll build a new Arc with it when ending the smart pointer frame.
46

47
            frame.tracker = Tracker::SmartPointer;
26✔
48

49
            let inner_layout = match pointee_shape.layout.sized_layout() {
26✔
50
                Ok(layout) => layout,
26✔
51
                Err(_) => {
NEW
52
                    return Err(ReflectError::Unsized {
×
NEW
53
                        shape: pointee_shape,
×
NEW
54
                        operation: "begin_smart_ptr, calculating inner value layout",
×
NEW
55
                    });
×
56
                }
57
            };
58
            let inner_ptr: *mut u8 = unsafe { ::alloc::alloc::alloc(inner_layout) };
26✔
59
            let Some(inner_ptr) = NonNull::new(inner_ptr) else {
26✔
NEW
60
                return Err(ReflectError::OperationFailed {
×
NEW
61
                    shape: frame.shape,
×
NEW
62
                    operation: "failed to allocate memory for smart pointer inner value",
×
NEW
63
                });
×
64
            };
65

66
            // Push a new frame for the inner value
67
            self.frames_mut().push(Frame::new(
26✔
68
                PtrUninit::new(inner_ptr),
26✔
69
                pointee_shape,
26✔
70
                FrameOwnership::Owned,
26✔
71
            ));
72
        } else {
73
            // pointee is unsized, we only support a handful of cases there
74
            if pointee_shape == str::SHAPE {
24✔
75
                crate::trace!("Pointee is str");
76

77
                // Allocate space for a String
78
                let string_layout = String::SHAPE
11✔
79
                    .layout
11✔
80
                    .sized_layout()
11✔
81
                    .expect("String must have a sized layout");
11✔
82
                let string_ptr: *mut u8 = unsafe { ::alloc::alloc::alloc(string_layout) };
11✔
83
                let Some(string_ptr) = NonNull::new(string_ptr) else {
11✔
NEW
84
                    return Err(ReflectError::OperationFailed {
×
NEW
85
                        shape: frame.shape,
×
NEW
86
                        operation: "failed to allocate memory for string",
×
NEW
87
                    });
×
88
                };
89
                let frame = Frame::new(
11✔
90
                    PtrUninit::new(string_ptr),
11✔
91
                    String::SHAPE,
92
                    FrameOwnership::Owned,
11✔
93
                );
94
                // Frame::new already sets tracker = Scalar and is_init = false
95
                self.frames_mut().push(frame);
11✔
96
            } else if let Type::Sequence(SequenceType::Slice(_st)) = pointee_shape.ty {
13✔
97
                crate::trace!("Pointee is [{}]", _st.t);
98

99
                // Get the slice builder vtable
100
                let slice_builder_vtable = smart_ptr_def.vtable.slice_builder_vtable.ok_or(
13✔
101
                    ReflectError::OperationFailed {
13✔
102
                        shape: frame.shape,
13✔
103
                        operation: "smart pointer does not support slice building",
13✔
104
                    },
13✔
NEW
105
                )?;
×
106

107
                // Create a new builder
108
                let builder_ptr = (slice_builder_vtable.new_fn)();
13✔
109

110
                // Deallocate the original Arc allocation before replacing with slice builder
111
                if let FrameOwnership::Owned = frame.ownership {
13✔
112
                    if let Ok(layout) = frame.shape.layout.sized_layout() {
13✔
113
                        if layout.size() > 0 {
13✔
114
                            unsafe {
13✔
115
                                ::alloc::alloc::dealloc(frame.data.as_mut_byte_ptr(), layout)
13✔
116
                            };
13✔
117
                        }
13✔
UNCOV
118
                    }
×
UNCOV
119
                }
×
120

121
                // Update the current frame to use the slice builder
122
                frame.data = builder_ptr.as_uninit();
13✔
123
                frame.tracker = Tracker::SmartPointerSlice {
13✔
124
                    vtable: slice_builder_vtable,
13✔
125
                    building_item: false,
13✔
126
                };
13✔
127
                // The slice builder memory is managed by the vtable, not by us
128
                frame.ownership = FrameOwnership::ManagedElsewhere;
13✔
129
            } else {
NEW
130
                return Err(ReflectError::OperationFailed {
×
NEW
131
                    shape: frame.shape,
×
NEW
132
                    operation: "push_smart_ptr can only be called on pointers to supported pointee types",
×
NEW
133
                });
×
134
            }
135
        }
136

137
        Ok(self)
50✔
138
    }
50✔
139
}
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