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

facet-rs / facet / 19662704846

25 Nov 2025 08:13AM UTC coverage: 53.944% (+0.9%) from 53.011%
19662704846

push

github

fasterthanlime
Add support for {de,}serialize_with

cf. https://github.com/facet-rs/facet/pull/916

135 of 209 new or added lines in 10 files covered. (64.59%)

4938 of 9154 relevant lines covered (53.94%)

44.63 hits per line

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

20.93
/facet-reflect/src/error.rs
1
use facet_core::{Characteristic, EnumType, FieldError, Shape, TryFromError};
2

3
/// A kind-only version of Tracker
4
#[allow(missing_docs)]
5
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
6
#[non_exhaustive]
7
pub enum TrackerKind {
8
    Uninit,
9
    Init,
10
    Array,
11
    Struct,
12
    SmartPointer,
13
    SmartPointerSlice,
14
    Enum,
15
    List,
16
    Map,
17
    Option,
18
}
19

20
/// Errors that can occur when reflecting on types.
21
#[derive(Clone)]
22
pub enum ReflectError {
23
    /// Tried to set an enum to a variant that does not exist
24
    NoSuchVariant {
25
        /// The enum definition containing all known variants.
26
        enum_type: EnumType,
27
    },
28

29
    /// Tried to get the wrong shape out of a value — e.g. we were manipulating
30
    /// a `String`, but `.get()` was called with a `u64` or something.
31
    WrongShape {
32
        /// The expected shape of the value.
33
        expected: &'static Shape,
34
        /// The actual shape of the value.
35
        actual: &'static Shape,
36
    },
37

38
    /// Attempted to perform an operation that expected a struct or something
39
    WasNotA {
40
        /// The name of the expected type.
41
        expected: &'static str,
42

43
        /// The type we got instead
44
        actual: &'static Shape,
45
    },
46

47
    /// A field was not initialized during build
48
    UninitializedField {
49
        /// The shape containing the field
50
        shape: &'static Shape,
51
        /// The name of the field that wasn't initialized
52
        field_name: &'static str,
53
    },
54

55
    /// A field in an enum variant was not initialized during build
56
    UninitializedEnumField {
57
        /// The enum shape
58
        shape: &'static Shape,
59
        /// The name of the field that wasn't initialized
60
        field_name: &'static str,
61
        /// The name of the variant containing the field
62
        variant_name: &'static str,
63
    },
64

65
    /// A scalar value was not initialized during build
66
    UninitializedValue {
67
        /// The scalar shape
68
        shape: &'static Shape,
69
    },
70

71
    /// An invariant of the reflection system was violated.
72
    InvariantViolation {
73
        /// The invariant that was violated.
74
        invariant: &'static str,
75
    },
76

77
    /// Attempted to set a value to its default, but the value doesn't implement `Default`.
78
    MissingCharacteristic {
79
        /// The shape of the value that doesn't implement `Default`.
80
        shape: &'static Shape,
81
        /// The characteristic that is missing.
82
        characteristic: Characteristic,
83
    },
84

85
    /// An operation failed for a given shape
86
    OperationFailed {
87
        /// The shape of the value for which the operation failed.
88
        shape: &'static Shape,
89
        /// The name of the operation that failed.
90
        operation: &'static str,
91
    },
92

93
    /// An error occurred when attempting to access or modify a field.
94
    FieldError {
95
        /// The shape of the value containing the field.
96
        shape: &'static Shape,
97
        /// The specific error that occurred with the field.
98
        field_error: FieldError,
99
    },
100

101
    /// Indicates that we try to access a field on an `Arc<T>`, for example, and the field might exist
102
    /// on the T, but you need to do begin_smart_ptr first when using the WIP API.
103
    MissingPushPointee {
104
        /// The smart pointer (`Arc<T>`, `Box<T>` etc.) shape on which field was caleld
105
        shape: &'static Shape,
106
    },
107

108
    /// An unknown error occurred.
109
    Unknown,
110

111
    /// An error occured while putting
112
    TryFromError {
113
        /// The shape of the value being converted from.
114
        src_shape: &'static Shape,
115

116
        /// The shape of the value being converted to.
117
        dst_shape: &'static Shape,
118

119
        /// The inner error
120
        inner: TryFromError,
121
    },
122

123
    /// A shape has a `default` attribute, but no implementation of the `Default` trait.
124
    DefaultAttrButNoDefaultImpl {
125
        /// The shape of the value that has a `default` attribute but no default implementation.
126
        shape: &'static Shape,
127
    },
128

129
    /// The type is unsized
130
    Unsized {
131
        /// The shape for the type that is unsized
132
        shape: &'static Shape,
133
        /// The operation we were trying to perform
134
        operation: &'static str,
135
    },
136

137
    /// Array not fully initialized during build
138
    ArrayNotFullyInitialized {
139
        /// The shape of the array
140
        shape: &'static Shape,
141
        /// The number of elements pushed
142
        pushed_count: usize,
143
        /// The expected array size
144
        expected_size: usize,
145
    },
146

147
    /// Array index out of bounds
148
    ArrayIndexOutOfBounds {
149
        /// The shape of the array
150
        shape: &'static Shape,
151
        /// The index that was out of bounds
152
        index: usize,
153
        /// The array size
154
        size: usize,
155
    },
156

157
    /// Invalid operation for the current state
158
    InvalidOperation {
159
        /// The operation that was attempted
160
        operation: &'static str,
161
        /// The reason why it failed
162
        reason: &'static str,
163
    },
164

165
    /// Unexpected tracker state when performing a reflection operation
166
    UnexpectedTracker {
167
        /// User-friendly message including operation that was being
168
        /// attempted
169
        message: &'static str,
170

171
        /// The current tracker set for this frame
172
        current_tracker: TrackerKind,
173
    },
174

175
    /// No active frame in Partial
176
    NoActiveFrame,
177

178
    /// steal_nth_field only works if the dst and src shapes
179
    /// are the same.
180
    HeistCancelledDifferentShapes {
181
        /// the shape we're stealing a field from
182
        src_shape: &'static Shape,
183
        /// the shape we're stealing a field for
184
        dst_shape: &'static Shape,
185
    },
186

187
    #[cfg(feature = "alloc")]
188
    /// Error during custom deserialization
189
    CustomDeserializationError {
190
        /// Error message provided by the deserialize_with method
191
        message: alloc::string::String,
192
        /// Shape that was passed to deserialize_with
193
        src_shape: &'static Shape,
194
        /// the shape of the target type
195
        dst_shape: &'static Shape,
196
    },
197

198
    #[cfg(feature = "alloc")]
199
    /// Error during custom serialization
200
    CustomSerializationError {
201
        /// Error message provided by the serialize_with method
202
        message: alloc::string::String,
203
        /// Shape that was passed to serialize_with
204
        src_shape: &'static Shape,
205
        /// the shape of the target
206
        dst_shape: &'static Shape,
207
    },
208
}
209

210
impl core::fmt::Display for ReflectError {
211
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
24✔
212
        match self {
24✔
213
            ReflectError::NoSuchVariant { enum_type } => {
×
214
                write!(f, "No such variant in enum. Known variants: ")?;
×
215
                for v in enum_type.variants {
×
216
                    write!(f, ", {}", v.name)?;
×
217
                }
218
                write!(f, ", that's it.")
×
219
            }
220
            ReflectError::WrongShape { expected, actual } => {
1✔
221
                write!(f, "Wrong shape: expected {expected}, but got {actual}")
1✔
222
            }
223
            ReflectError::WasNotA { expected, actual } => {
×
224
                write!(f, "Wrong shape: expected {expected}, but got {actual}")
×
225
            }
226
            ReflectError::UninitializedField { shape, field_name } => {
4✔
227
                write!(f, "Field '{shape}::{field_name}' was not initialized")
4✔
228
            }
229
            ReflectError::UninitializedEnumField {
230
                shape,
×
231
                field_name,
×
232
                variant_name,
×
233
            } => {
234
                write!(
×
235
                    f,
×
236
                    "Field '{shape}::{field_name}' in variant '{variant_name}' was not initialized"
×
237
                )
238
            }
239
            ReflectError::UninitializedValue { shape } => {
8✔
240
                write!(f, "Value '{shape}' was not initialized")
8✔
241
            }
242
            ReflectError::InvariantViolation { invariant } => {
4✔
243
                write!(f, "Invariant violation: {invariant}")
4✔
244
            }
245
            ReflectError::MissingCharacteristic {
246
                shape,
×
247
                characteristic,
×
248
            } => write!(
×
249
                f,
×
250
                "{shape} does not implement characteristic {characteristic:?}",
×
251
            ),
252
            ReflectError::OperationFailed { shape, operation } => {
4✔
253
                write!(f, "Operation failed on shape {shape}: {operation}")
4✔
254
            }
255
            ReflectError::FieldError { shape, field_error } => {
2✔
256
                write!(f, "Field error for shape {shape}: {field_error}")
2✔
257
            }
258
            ReflectError::MissingPushPointee { shape } => {
×
259
                write!(
×
260
                    f,
×
261
                    "Tried to access a field on smart pointer '{shape}', but you need to call .begin_smart_ptr() first to work with the value it points to (and pop it with .pop() later)"
×
262
                )
263
            }
264
            ReflectError::Unknown => write!(f, "Unknown error"),
×
265
            ReflectError::TryFromError {
266
                src_shape,
×
267
                dst_shape,
×
268
                inner,
×
269
            } => {
270
                write!(
×
271
                    f,
×
272
                    "While trying to put {src_shape} into a {dst_shape}: {inner}"
×
273
                )
274
            }
275
            ReflectError::DefaultAttrButNoDefaultImpl { shape } => write!(
×
276
                f,
×
277
                "Shape '{shape}' has a `default` attribute but no default implementation"
×
278
            ),
279
            ReflectError::Unsized { shape, operation } => write!(
1✔
280
                f,
1✔
281
                "Shape '{shape}' is unsized, can't perform operation {operation}"
1✔
282
            ),
283
            ReflectError::ArrayNotFullyInitialized {
284
                shape,
×
285
                pushed_count,
×
286
                expected_size,
×
287
            } => {
288
                write!(
×
289
                    f,
×
290
                    "Array '{shape}' not fully initialized: expected {expected_size} elements, but got {pushed_count}"
×
291
                )
292
            }
293
            ReflectError::ArrayIndexOutOfBounds { shape, index, size } => {
×
294
                write!(
×
295
                    f,
×
296
                    "Array index {index} out of bounds for '{shape}' (array length is {size})"
×
297
                )
298
            }
299
            ReflectError::InvalidOperation { operation, reason } => {
×
300
                write!(f, "Invalid operation '{operation}': {reason}")
×
301
            }
302
            ReflectError::UnexpectedTracker {
303
                message,
×
304
                current_tracker,
×
305
            } => {
306
                write!(f, "{message}: current tracker is {current_tracker:?}")
×
307
            }
308
            ReflectError::NoActiveFrame => {
309
                write!(f, "No active frame in Partial")
×
310
            }
311
            ReflectError::HeistCancelledDifferentShapes {
312
                src_shape,
×
313
                dst_shape,
×
314
            } => {
315
                write!(
×
316
                    f,
×
317
                    "Tried to steal_nth_field from {src_shape} into {dst_shape}"
×
318
                )
319
            }
320
            #[cfg(feature = "alloc")]
321
            ReflectError::CustomDeserializationError {
NEW
322
                message,
×
NEW
323
                src_shape,
×
NEW
324
                dst_shape,
×
325
            } => {
NEW
326
                write!(
×
NEW
327
                    f,
×
NEW
328
                    "Custom deserialization of shape '{src_shape}' into '{dst_shape}' failed: {message}"
×
329
                )
330
            }
331
            #[cfg(feature = "alloc")]
332
            ReflectError::CustomSerializationError {
NEW
333
                message,
×
NEW
334
                src_shape,
×
NEW
335
                dst_shape,
×
336
            } => {
NEW
337
                write!(
×
NEW
338
                    f,
×
NEW
339
                    "Custom serialization of shape '{src_shape}' into '{dst_shape}' failed: {message}"
×
340
                )
341
            }
342
        }
343
    }
24✔
344
}
345

346
impl core::fmt::Debug for ReflectError {
347
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
×
348
        // Use Display implementation for more readable output
349
        write!(f, "ReflectError({self})")
×
350
    }
×
351
}
352

353
impl core::error::Error for ReflectError {}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc