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

facet-rs / facet / 16482665288

23 Jul 2025 09:56PM UTC coverage: 58.441% (-0.2%) from 58.68%
16482665288

Pull #855

github

web-flow
Merge 1ef12fa0a into 5e8e214d1
Pull Request #855: wip: Remove 'shape lifetime

399 of 571 new or added lines in 70 files covered. (69.88%)

3 existing lines in 3 files now uncovered.

11939 of 20429 relevant lines covered (58.44%)

120.56 hits per line

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

57.0
/facet-msgpack/src/deserialize.rs
1
use crate::constants::*;
2
use crate::errors::Error as DecodeError;
3

4
use facet_core::{Def, Facet, Type, UserType};
5
use facet_reflect::Partial;
6
use log::trace;
7

8
/// Deserializes MessagePack-encoded data into a type that implements `Facet`.
9
///
10
/// # Example
11
/// ```
12
/// use facet::Facet;
13
/// use facet_msgpack::from_slice;
14
///
15
/// #[derive(Debug, Facet, PartialEq)]
16
/// struct User {
17
///     id: u64,
18
///     username: String,
19
/// }
20
///
21
/// // MessagePack binary data (equivalent to {"id": 42, "username": "user123"})
22
/// let msgpack_data = [
23
///     0x82, 0xa2, 0x69, 0x64, 0x2a, 0xa8, 0x75, 0x73,
24
///     0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0xa7, 0x75,
25
///     0x73, 0x65, 0x72, 0x31, 0x32, 0x33
26
/// ];
27
///
28
/// let user: User = from_slice(&msgpack_data).unwrap();
29
/// assert_eq!(user, User { id: 42, username: "user123".to_string() });
30
/// ```
31
pub fn from_slice<T: Facet<'static>>(msgpack: &[u8]) -> Result<T, DecodeError> {
21✔
32
    // FIXME: why is the bound `'static` up there? msgpack can borrow from the input afaict?
33

34
    trace!("from_slice: Starting deserialization for type {}", T::SHAPE);
21✔
35
    let mut typed_partial = Partial::alloc::<T>()?;
21✔
36
    trace!(
21✔
37
        "from_slice: Allocated TypedPartial, inner shape: {}",
21✔
38
        typed_partial.inner_mut().shape()
21✔
39
    );
40
    from_slice_value(msgpack, typed_partial.inner_mut())?;
21✔
41
    trace!("from_slice: Deserialization complete, building value");
19✔
42
    let boxed_value = typed_partial.build()?;
19✔
43
    trace!("from_slice: Value built successfully");
19✔
44
    Ok(*boxed_value)
19✔
45
}
21✔
46

47
/// Deserializes MessagePack-encoded data into a Facet value.
48
///
49
/// This function takes a MessagePack byte array and populates a Partial object
50
/// according to the shape description, returning an Opaque value.
51
///
52
/// # Example
53
///
54
/// ```
55
/// use facet::Facet;
56
/// use facet_msgpack::from_slice;
57
///
58
/// #[derive(Debug, Facet, PartialEq)]
59
/// struct User {
60
///     id: u64,
61
///     username: String,
62
/// }
63
///
64
/// // MessagePack binary data (equivalent to {"id": 42, "username": "user123"})
65
/// let msgpack_data = [
66
///     0x82, 0xa2, 0x69, 0x64, 0x2a, 0xa8, 0x75, 0x73,
67
///     0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0xa7, 0x75,
68
///     0x73, 0x65, 0x72, 0x31, 0x32, 0x33
69
/// ];
70
///
71
/// let user: User = from_slice(&msgpack_data).unwrap();
72
/// assert_eq!(user, User { id: 42, username: "user123".to_string() });
73
/// ```
74
///
75
/// # Parameters
76
/// * `wip` - A Partial object that will be filled with deserialized data
77
/// * `msgpack` - A byte slice containing MessagePack-encoded data
78
///
79
/// # Returns
80
/// * `Ok(Opaque)` containing the deserialized data if successful
81
/// * `Err(DecodeError)` if an error occurred during deserialization
82
///
83
/// # MessagePack Format
84
/// This implementation follows the MessagePack specification:
85
/// <https://github.com/msgpack/msgpack/blob/master/spec.md>
86
pub fn from_slice_value<'facet>(
23✔
87
    msgpack: &[u8],
23✔
88
    wip: &mut Partial<'facet>,
23✔
89
) -> Result<(), DecodeError> {
23✔
90
    trace!("from_slice_value: Starting with shape {}", wip.shape());
23✔
91
    let mut decoder = Decoder::new(msgpack);
23✔
92
    let result = decoder.deserialize_value(wip);
23✔
93
    match &result {
23✔
94
        Ok(_) => trace!("from_slice_value: Deserialization successful"),
21✔
95
        Err(e) => trace!("from_slice_value: Deserialization failed: {e:?}"),
2✔
96
    }
97
    result
23✔
98
}
23✔
99

100
struct Decoder<'input> {
101
    input: &'input [u8],
102
    offset: usize,
103
}
104

105
impl<'input> Decoder<'input> {
106
    fn new(input: &'input [u8]) -> Self {
23✔
107
        Decoder { input, offset: 0 }
23✔
108
    }
23✔
109

110
    /// Decodes a single byte from the input.
111
    /// This is a low-level method used by other decoders.
112
    fn decode_u8(&mut self) -> Result<u8, DecodeError> {
96✔
113
        if self.offset >= self.input.len() {
96✔
114
            return Err(DecodeError::InsufficientData);
1✔
115
        }
95✔
116
        let value = self.input[self.offset];
95✔
117
        self.offset += 1;
95✔
118
        Ok(value)
95✔
119
    }
96✔
120

121
    /// Decodes a 16-bit unsigned integer in big-endian byte order.
122
    /// This is a low-level method used by other decoders.
123
    fn decode_u16(&mut self) -> Result<u16, DecodeError> {
1✔
124
        if self.offset + 2 > self.input.len() {
1✔
125
            return Err(DecodeError::InsufficientData);
×
126
        }
1✔
127
        let value =
1✔
128
            u16::from_be_bytes(self.input[self.offset..self.offset + 2].try_into().unwrap());
1✔
129
        self.offset += 2;
1✔
130
        Ok(value)
1✔
131
    }
1✔
132

133
    /// Decodes a 32-bit unsigned integer in big-endian byte order.
134
    /// This is a low-level method used by other decoders.
135
    fn decode_u32(&mut self) -> Result<u32, DecodeError> {
3✔
136
        if self.offset + 4 > self.input.len() {
3✔
137
            return Err(DecodeError::InsufficientData);
×
138
        }
3✔
139
        let value =
3✔
140
            u32::from_be_bytes(self.input[self.offset..self.offset + 4].try_into().unwrap());
3✔
141
        self.offset += 4;
3✔
142
        Ok(value)
3✔
143
    }
3✔
144

145
    /// Decodes a MessagePack-encoded unsigned 64-bit integer.
146
    /// Handles the following MessagePack types:
147
    /// - positive fixint (0x00 - 0x7f): single-byte positive integer
148
    /// - uint8 (0xcc): 8-bit unsigned integer
149
    /// - uint16 (0xcd): 16-bit unsigned integer (big-endian)
150
    /// - uint32 (0xce): 32-bit unsigned integer (big-endian)
151
    /// - uint64 (0xcf): 64-bit unsigned integer (big-endian)
152
    ///
153
    /// Ref: <https://github.com/msgpack/msgpack/blob/master/spec.md#int-format-family>
154
    fn decode_u64(&mut self) -> Result<u64, DecodeError> {
22✔
155
        match self.decode_u8()? {
22✔
156
            MSGPACK_UINT8 => Ok(self.decode_u8()? as u64),
×
157
            MSGPACK_UINT16 => Ok(self.decode_u16()? as u64),
1✔
158
            MSGPACK_UINT32 => Ok(self.decode_u32()? as u64),
3✔
159
            MSGPACK_UINT64 => {
160
                if self.offset + 8 > self.input.len() {
×
161
                    return Err(DecodeError::InsufficientData);
×
162
                }
×
163
                let value = u64::from_be_bytes(
×
164
                    self.input[self.offset..self.offset + 8].try_into().unwrap(),
×
165
                );
166
                self.offset += 8;
×
167
                Ok(value)
×
168
            }
169
            prefix @ MSGPACK_POSFIXINT_MIN..=MSGPACK_POSFIXINT_MAX => Ok(prefix as u64),
18✔
170
            _ => Err(DecodeError::UnexpectedType),
×
171
        }
172
    }
22✔
173

174
    /// Decodes a MessagePack-encoded string.
175
    /// Handles the following MessagePack types:
176
    /// - fixstr (0xa0 - 0xbf): string up to 31 bytes
177
    /// - str8 (0xd9): string up to 255 bytes
178
    /// - str16 (0xda): string up to 65535 bytes
179
    /// - str32 (0xdb): string up to 4294967295 bytes
180
    ///
181
    /// Ref: <https://github.com/msgpack/msgpack/blob/master/spec.md#formats-str>
182
    fn decode_string(&mut self) -> Result<String, DecodeError> {
43✔
183
        let prefix = self.decode_u8()?;
43✔
184

185
        let len = match prefix {
42✔
186
            prefix @ MSGPACK_FIXSTR_MIN..=MSGPACK_FIXSTR_MAX => (prefix & 0x1f) as usize,
42✔
187
            MSGPACK_STR8 => self.decode_u8()? as usize,
×
188
            MSGPACK_STR16 => self.decode_u16()? as usize,
×
189
            MSGPACK_STR32 => self.decode_u32()? as usize,
×
190
            _ => return Err(DecodeError::UnexpectedType),
1✔
191
        };
192

193
        if self.offset + len > self.input.len() {
41✔
194
            return Err(DecodeError::InsufficientData);
×
195
        }
41✔
196

197
        let value = String::from_utf8(self.input[self.offset..self.offset + len].to_vec())
41✔
198
            .map_err(|_| DecodeError::InvalidData)?;
41✔
199
        self.offset += len;
41✔
200
        Ok(value)
41✔
201
    }
43✔
202

203
    /// Decodes a MessagePack-encoded map length.
204
    /// Handles the following MessagePack types:
205
    /// - fixmap (0x80 - 0x8f): map with up to 15 elements
206
    /// - map16 (0xde): map with up to 65535 elements
207
    /// - map32 (0xdf): map with up to 4294967295 elements
208
    ///
209
    /// Ref: <https://github.com/msgpack/msgpack/blob/master/spec.md#formats-map>
210
    fn decode_map_len(&mut self) -> Result<usize, DecodeError> {
16✔
211
        let prefix = self.decode_u8()?;
16✔
212

213
        match prefix {
16✔
214
            prefix @ MSGPACK_FIXMAP_MIN..=MSGPACK_FIXMAP_MAX => Ok((prefix & 0x0f) as usize),
16✔
215
            MSGPACK_MAP16 => Ok(self.decode_u16()? as usize),
×
216
            MSGPACK_MAP32 => Ok(self.decode_u32()? as usize),
×
217
            _ => Err(DecodeError::UnexpectedType),
×
218
        }
219
    }
16✔
220

221
    /// Decodes a MessagePack-encoded array length.
222
    /// Handles the following MessagePack types:
223
    /// - fixarray (0x90 - 0x9f): array with up to 15 elements
224
    /// - array16 (0xdc): array with up to 65535 elements
225
    /// - array32 (0xdd): array with up to 4294967295 elements
226
    ///
227
    /// Ref: <https://github.com/msgpack/msgpack/blob/master/spec.md#formats-array>
228
    #[allow(dead_code)]
229
    fn decode_array_len(&mut self) -> Result<usize, DecodeError> {
11✔
230
        let prefix = self.decode_u8()?;
11✔
231

232
        match prefix {
11✔
233
            prefix @ MSGPACK_FIXARRAY_MIN..=MSGPACK_FIXARRAY_MAX => Ok((prefix & 0x0f) as usize),
11✔
234
            MSGPACK_ARRAY16 => Ok(self.decode_u16()? as usize),
×
235
            MSGPACK_ARRAY32 => Ok(self.decode_u32()? as usize),
×
236
            _ => Err(DecodeError::UnexpectedType),
×
237
        }
238
    }
11✔
239

240
    /// Decodes a MessagePack-encoded boolean value.
241
    /// Handles the following MessagePack types:
242
    /// - true (0xc3): boolean true
243
    /// - false (0xc2): boolean false
244
    ///
245
    /// Ref: <https://github.com/msgpack/msgpack/blob/master/spec.md#formats-bool>
246
    fn decode_bool(&mut self) -> Result<bool, DecodeError> {
3✔
247
        match self.decode_u8()? {
3✔
248
            MSGPACK_TRUE => Ok(true),
1✔
249
            MSGPACK_FALSE => Ok(false),
2✔
250
            _ => Err(DecodeError::UnexpectedType),
×
251
        }
252
    }
3✔
253

254
    /// Decodes a MessagePack-encoded nil value.
255
    /// Handles the following MessagePack types:
256
    /// - nil (0xc0): nil/null value
257
    ///
258
    /// Ref: <https://github.com/msgpack/msgpack/blob/master/spec.md#formats-nil>
259
    #[allow(dead_code)]
260
    fn decode_nil(&mut self) -> Result<(), DecodeError> {
1✔
261
        match self.decode_u8()? {
1✔
262
            MSGPACK_NIL => Ok(()),
1✔
263
            _ => Err(DecodeError::UnexpectedType),
×
264
        }
265
    }
1✔
266

267
    /// Peeks at the next byte to check if it's a nil value without advancing the offset.
268
    /// Returns true if the next value is nil, false otherwise.
269
    #[allow(dead_code)]
270
    fn peek_nil(&mut self) -> Result<bool, DecodeError> {
3✔
271
        if self.offset >= self.input.len() {
3✔
272
            return Err(DecodeError::InsufficientData);
×
273
        }
3✔
274
        Ok(self.input[self.offset] == MSGPACK_NIL)
3✔
275
    }
3✔
276

277
    /// Peeks at the next byte to check if it's a string value without advancing the offset.
278
    /// Returns true if the next value is a string, false otherwise.
279
    fn peek_string(&mut self) -> Result<bool, DecodeError> {
3✔
280
        if self.offset >= self.input.len() {
3✔
281
            return Err(DecodeError::InsufficientData);
×
282
        }
3✔
283
        let prefix = self.input[self.offset];
3✔
284
        Ok((MSGPACK_FIXSTR_MIN..=MSGPACK_FIXSTR_MAX).contains(&prefix)
3✔
285
            || prefix == MSGPACK_STR8
1✔
286
            || prefix == MSGPACK_STR16
1✔
287
            || prefix == MSGPACK_STR32)
1✔
288
    }
3✔
289

290
    /// Skips a MessagePack value of any type.
291
    /// This is used when encountering unknown field names in a struct.
NEW
292
    fn skip_value(&mut self) -> Result<(), DecodeError> {
×
293
        let prefix = self.decode_u8()?;
×
294

295
        match prefix {
×
296
            // String formats
297
            prefix @ MSGPACK_FIXSTR_MIN..=MSGPACK_FIXSTR_MAX => {
×
298
                let len = (prefix & 0x1f) as usize;
×
299
                if self.offset + len > self.input.len() {
×
300
                    return Err(DecodeError::InsufficientData);
×
301
                }
×
302
                self.offset += len;
×
303
                Ok(())
×
304
            }
305
            MSGPACK_STR8 => {
306
                let len = self.decode_u8()? as usize;
×
307
                if self.offset + len > self.input.len() {
×
308
                    return Err(DecodeError::InsufficientData);
×
309
                }
×
310
                self.offset += len;
×
311
                Ok(())
×
312
            }
313
            MSGPACK_STR16 => {
314
                let len = self.decode_u16()? as usize;
×
315
                if self.offset + len > self.input.len() {
×
316
                    return Err(DecodeError::InsufficientData);
×
317
                }
×
318
                self.offset += len;
×
319
                Ok(())
×
320
            }
321
            MSGPACK_STR32 => {
322
                let len = self.decode_u32()? as usize;
×
323
                if self.offset + len > self.input.len() {
×
324
                    return Err(DecodeError::InsufficientData);
×
325
                }
×
326
                self.offset += len;
×
327
                Ok(())
×
328
            }
329

330
            // Integer formats
331
            MSGPACK_UINT8 => {
332
                self.offset += 1;
×
333
                Ok(())
×
334
            }
335
            MSGPACK_UINT16 => {
336
                self.offset += 2;
×
337
                Ok(())
×
338
            }
339
            MSGPACK_UINT32 => {
340
                self.offset += 4;
×
341
                Ok(())
×
342
            }
343
            MSGPACK_UINT64 => {
344
                self.offset += 8;
×
345
                Ok(())
×
346
            }
347
            MSGPACK_INT8 => {
348
                self.offset += 1;
×
349
                Ok(())
×
350
            }
351
            MSGPACK_INT16 => {
352
                self.offset += 2;
×
353
                Ok(())
×
354
            }
355
            MSGPACK_INT32 => {
356
                self.offset += 4;
×
357
                Ok(())
×
358
            }
359
            MSGPACK_INT64 => {
360
                self.offset += 8;
×
361
                Ok(())
×
362
            }
363
            // Fixed integers are already handled by decode_u8
364

365
            // Boolean and nil
366
            MSGPACK_NIL | MSGPACK_TRUE | MSGPACK_FALSE => Ok(()),
×
367

368
            // Map format
369
            prefix @ MSGPACK_FIXMAP_MIN..=MSGPACK_FIXMAP_MAX => {
×
370
                let len = (prefix & 0x0f) as usize;
×
371
                for _ in 0..len {
×
372
                    self.skip_value()?; // Skip key
×
373
                    self.skip_value()?; // Skip value
×
374
                }
375
                Ok(())
×
376
            }
377
            MSGPACK_MAP16 => {
378
                let len = self.decode_u16()? as usize;
×
379
                for _ in 0..len {
×
380
                    self.skip_value()?; // Skip key
×
381
                    self.skip_value()?; // Skip value
×
382
                }
383
                Ok(())
×
384
            }
385
            MSGPACK_MAP32 => {
386
                let len = self.decode_u32()? as usize;
×
387
                for _ in 0..len {
×
388
                    self.skip_value()?; // Skip key
×
389
                    self.skip_value()?; // Skip value
×
390
                }
391
                Ok(())
×
392
            }
393

394
            // Array format
395
            prefix @ MSGPACK_FIXARRAY_MIN..=MSGPACK_FIXARRAY_MAX => {
×
396
                let len = (prefix & 0x0f) as usize;
×
397
                for _ in 0..len {
×
398
                    self.skip_value()?;
×
399
                }
400
                Ok(())
×
401
            }
402
            MSGPACK_ARRAY16 => {
403
                let len = self.decode_u16()? as usize;
×
404
                for _ in 0..len {
×
405
                    self.skip_value()?;
×
406
                }
407
                Ok(())
×
408
            }
409
            MSGPACK_ARRAY32 => {
410
                let len = self.decode_u32()? as usize;
×
411
                for _ in 0..len {
×
412
                    self.skip_value()?;
×
413
                }
414
                Ok(())
×
415
            }
416

417
            _ => Err(DecodeError::UnexpectedType),
×
418
        }
419
    }
×
420

421
    fn deserialize_value<'facet>(&mut self, wip: &mut Partial<'facet>) -> Result<(), DecodeError> {
74✔
422
        let shape = wip.shape();
74✔
423
        trace!("Deserializing {shape:?}");
74✔
424

425
        // First check the type system (Type)
426
        match &shape.ty {
5✔
427
            Type::User(UserType::Struct(struct_type))
17✔
428
                if struct_type.kind != facet_core::StructKind::Tuple =>
17✔
429
            {
430
                trace!("Deserializing struct");
12✔
431
                let map_len = self.decode_map_len()?;
12✔
432

433
                // Track which fields we've seen so we can handle defaults for the rest
434
                let mut seen_fields = vec![false; struct_type.fields.len()];
12✔
435

436
                for _ in 0..map_len {
12✔
437
                    let key = self.decode_string()?;
19✔
438
                    match wip.field_index(&key) {
18✔
439
                        Some(index) => {
18✔
440
                            seen_fields[index] = true;
18✔
441
                            self.deserialize_value(wip.begin_nth_field(index).unwrap())?;
18✔
442
                            wip.end().unwrap();
17✔
443
                        }
444
                        None => {
445
                            // Skip unknown field value
446
                            self.skip_value()?;
×
447
                            trace!("Skipping unknown field: {key}");
×
448
                        }
449
                    }
450
                }
451

452
                // Handle defaults for fields that weren't seen in the input
453
                for (i, &seen) in seen_fields.iter().enumerate() {
16✔
454
                    if !seen {
16✔
455
                        let field = &struct_type.fields[i];
1✔
456
                        if field.flags.contains(facet_core::FieldFlags::DEFAULT) {
1✔
457
                            wip.begin_nth_field(i)?;
1✔
458

459
                            // Check for field-level default function first, then type-level default
460
                            if let Some(field_default_fn) = field.vtable.default_fn {
1✔
461
                                wip.set_field_default(field_default_fn)?;
×
462
                            } else {
463
                                wip.set_default()?;
1✔
464
                            }
465

466
                            wip.end()?;
1✔
467
                        } else {
468
                            // Non-default field was missing
469
                            return Err(DecodeError::MissingField(field.name.to_string()));
×
470
                        }
471
                    }
15✔
472
                }
473

474
                return Ok(());
10✔
475
            }
476
            Type::User(facet_core::UserType::Struct(struct_type))
5✔
477
                if struct_type.kind == facet_core::StructKind::Tuple =>
5✔
478
            {
479
                trace!("Deserializing tuple");
5✔
480
                let array_len = self.decode_array_len()?;
5✔
481
                let field_count = struct_type.fields.len();
5✔
482

483
                if array_len != field_count {
5✔
484
                    return Err(DecodeError::InvalidData);
×
485
                }
5✔
486

487
                // For tuples, deserialize fields in order
488
                for idx in 0..field_count {
9✔
489
                    trace!("Deserializing tuple field {idx}");
9✔
490
                    wip.begin_nth_field(idx)?;
9✔
491
                    self.deserialize_value(wip)?;
9✔
492
                    wip.end().map_err(DecodeError::ReflectError)?;
9✔
493
                }
494

495
                return Ok(());
5✔
496
            }
497
            Type::User(UserType::Enum(enum_type)) => {
3✔
498
                trace!("Deserializing enum");
3✔
499

500
                // Check if it's a unit variant which is represented as a string
501
                if self.peek_string()? {
3✔
502
                    let variant_name = self.decode_string()?;
2✔
503
                    for (idx, variant) in enum_type.variants.iter().enumerate() {
3✔
504
                        if variant.name == variant_name {
3✔
505
                            wip.select_nth_variant(idx)?;
2✔
506
                            return Ok(());
2✔
507
                        }
1✔
508
                    }
509
                    return Err(DecodeError::InvalidEnum(format!(
×
510
                        "Unknown variant: {variant_name}"
×
511
                    )));
×
512
                }
1✔
513

514
                // Otherwise it's represented as a map with single entry where key is the variant name
515
                let map_len = self.decode_map_len()?;
1✔
516
                if map_len != 1 {
1✔
517
                    return Err(DecodeError::InvalidData);
×
518
                }
1✔
519

520
                let variant_name = self.decode_string()?;
1✔
521

522
                for (idx, variant) in enum_type.variants.iter().enumerate() {
2✔
523
                    if variant.name == variant_name {
2✔
524
                        match &variant.data.kind {
1✔
525
                            // Handle unit variant
526
                            facet_core::StructKind::Unit => {
527
                                // Need to skip any value that might be present
528
                                self.skip_value()?;
×
529
                                wip.select_nth_variant(idx)?;
×
530
                                return Ok(());
×
531
                            }
532

533
                            // Handle tuple variant
534
                            facet_core::StructKind::Tuple => {
535
                                let array_len = self.decode_array_len()?;
×
536
                                let field_count = variant.data.fields.len();
×
537

538
                                if array_len != field_count {
×
539
                                    return Err(DecodeError::InvalidData);
×
540
                                }
×
541

542
                                wip.select_nth_variant(idx)?;
×
543
                                for field_idx in 0..field_count {
×
544
                                    wip.begin_nth_enum_field(field_idx)?;
×
545
                                    self.deserialize_value(wip)?;
×
546
                                    wip.end()?;
×
547
                                }
548
                                return Ok(());
×
549
                            }
550

551
                            // Handle struct variant
552
                            facet_core::StructKind::Struct => {
553
                                let map_len = self.decode_map_len()?;
1✔
554
                                wip.select_nth_variant(idx)?;
1✔
555

556
                                // Handle fields as a normal struct
557
                                for _ in 0..map_len {
1✔
558
                                    let field_name = self.decode_string()?;
3✔
559
                                    match wip.field_index(&field_name) {
3✔
560
                                        Some(field_idx) => {
3✔
561
                                            wip.begin_nth_enum_field(field_idx)?;
3✔
562
                                            self.deserialize_value(wip)?;
3✔
563
                                            wip.end()?;
3✔
564
                                        }
565
                                        None => {
566
                                            // Skip unknown field
567
                                            self.skip_value()?;
×
568
                                            trace!("Skipping unknown field in enum: {field_name}");
×
569
                                        }
570
                                    }
571
                                }
572

573
                                return Ok(());
1✔
574
                            }
575

576
                            // Handle other kinds that might be added in the future
577
                            _ => {
578
                                return Err(DecodeError::UnsupportedType(format!(
×
579
                                    "Unsupported enum variant kind: {:?}",
×
580
                                    variant.data.kind
×
581
                                )));
×
582
                            }
583
                        }
584
                    }
1✔
585
                }
586

587
                return Err(DecodeError::InvalidEnum(format!(
×
588
                    "Unknown variant: {variant_name}"
×
589
                )));
×
590
            }
591
            _ => {}
54✔
592
        }
593

594
        // Then check the def system (Def)
595
        if let Def::Scalar = shape.def {
54✔
596
            trace!("Deserializing scalar");
43✔
597
            if shape.is_type::<String>() {
43✔
598
                let s = self.decode_string()?;
18✔
599
                wip.set(s)?;
17✔
600
            } else if shape.is_type::<u64>() {
25✔
601
                let n = self.decode_u64()?;
15✔
602
                wip.set(n)?;
15✔
603
            } else if shape.is_type::<u32>() {
10✔
604
                let n = self.decode_u64()?;
×
605
                if n > u32::MAX as u64 {
×
606
                    return Err(DecodeError::IntegerOverflow);
×
607
                }
×
608
                wip.set(n as u32)?;
×
609
            } else if shape.is_type::<u16>() {
10✔
610
                let n = self.decode_u64()?;
×
611
                if n > u16::MAX as u64 {
×
612
                    return Err(DecodeError::IntegerOverflow);
×
613
                }
×
614
                wip.set(n as u16)?;
×
615
            } else if shape.is_type::<u8>() {
10✔
616
                let n = self.decode_u64()?;
×
617
                if n > u8::MAX as u64 {
×
618
                    return Err(DecodeError::IntegerOverflow);
×
619
                }
×
620
                wip.set(n as u8)?;
×
621
            } else if shape.is_type::<i64>() {
10✔
622
                // TODO: implement proper signed int decoding including negative values
623
                let n = self.decode_u64()?;
×
624
                if n > i64::MAX as u64 {
×
625
                    return Err(DecodeError::IntegerOverflow);
×
626
                }
×
627
                wip.set(n as i64)?;
×
628
            } else if shape.is_type::<i32>() {
10✔
629
                let n = self.decode_u64()?;
7✔
630
                if n > i32::MAX as u64 {
7✔
631
                    return Err(DecodeError::IntegerOverflow);
×
632
                }
7✔
633
                wip.set(n as i32)?;
7✔
634
            } else if shape.is_type::<i16>() {
3✔
635
                let n = self.decode_u64()?;
×
636
                if n > i16::MAX as u64 {
×
637
                    return Err(DecodeError::IntegerOverflow);
×
638
                }
×
639
                wip.set(n as i16)?;
×
640
            } else if shape.is_type::<i8>() {
3✔
641
                let n = self.decode_u64()?;
×
642
                if n > i8::MAX as u64 {
×
643
                    return Err(DecodeError::IntegerOverflow);
×
644
                }
×
645
                wip.set(n as i8)?;
×
646
            } else if shape.is_type::<f64>() {
3✔
647
                // TODO: Implement proper f64 decoding from MessagePack format
648
                return Err(DecodeError::NotImplemented(
×
649
                    "f64 deserialization not yet implemented".to_string(),
×
650
                ));
×
651
            } else if shape.is_type::<f32>() {
3✔
652
                // TODO: Implement proper f32 decoding from MessagePack format
653
                return Err(DecodeError::NotImplemented(
×
654
                    "f32 deserialization not yet implemented".to_string(),
×
655
                ));
×
656
            } else if shape.is_type::<bool>() {
3✔
657
                let b = self.decode_bool()?;
3✔
658
                wip.set(b)?;
3✔
659
            } else {
660
                return Err(DecodeError::UnsupportedType(format!("{shape}")));
×
661
            }
662
        } else if let Def::Map(_map_def) = shape.def {
11✔
663
            trace!("Deserializing map");
2✔
664
            let map_len = self.decode_map_len()?;
2✔
665
            wip.begin_map()?;
2✔
666

667
            for _ in 0..map_len {
2✔
668
                // Each map entry has a key and value
669
                wip.begin_key()?;
3✔
670
                self.deserialize_value(wip)?;
3✔
671
                wip.end()?;
3✔
672

673
                wip.begin_value()?;
3✔
674
                self.deserialize_value(wip)?;
3✔
675
                wip.end()?;
3✔
676
            }
677
        } else if let Def::List(_list_def) = shape.def {
9✔
678
            trace!("Deserializing list");
6✔
679
            let array_len = self.decode_array_len()?;
6✔
680
            wip.begin_list()?;
6✔
681

682
            for _ in 0..array_len {
6✔
683
                wip.begin_list_item()?;
13✔
684
                self.deserialize_value(wip)?;
13✔
685
                wip.end()?;
13✔
686
            }
687
        } else if let Def::Option(_option_def) = shape.def {
3✔
688
            trace!("Deserializing option with shape: {shape}");
3✔
689
            if self.peek_nil()? {
3✔
690
                trace!("Option value is nil, setting to None");
1✔
691
                // Consume the nil value
692
                self.decode_nil()?;
1✔
693
                // Initialize None option
694
                wip.set_default()?;
1✔
695
            } else {
696
                trace!("Option value is present, setting to Some");
2✔
697
                // Value is present - initialize a Some option
698
                wip.begin_some()?;
2✔
699
                trace!("After begin_some, wip shape: {}", wip.shape());
2✔
700
                self.deserialize_value(wip)?;
2✔
701
                trace!("After deserialize_value, calling end");
2✔
702
                wip.end()?;
2✔
703
                trace!("After end, wip shape: {}", wip.shape());
2✔
704
            }
705
        } else {
706
            return Err(DecodeError::UnsupportedShape(format!("{shape:?}")));
×
707
        }
708

709
        Ok(())
53✔
710
    }
74✔
711
}
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