Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions src/deserialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ impl<'input> Decoder<'input> {
// First check the type system (Type)
match &shape.ty {
Type::User(UserType::Struct(struct_type))
if struct_type.kind != facet_core::StructKind::Tuple =>
if struct_type.kind == facet_core::StructKind::Struct =>
{
trace!("Deserializing struct");
let map_len = self.decode_map_len()?;
Expand Down Expand Up @@ -474,7 +474,8 @@ impl<'input> Decoder<'input> {
return Ok(());
}
Type::User(facet_core::UserType::Struct(struct_type))
if struct_type.kind == facet_core::StructKind::Tuple =>
if struct_type.kind == facet_core::StructKind::Tuple
|| struct_type.kind == facet_core::StructKind::TupleStruct =>
{
trace!("Deserializing tuple");
let array_len = self.decode_array_len()?;
Expand Down Expand Up @@ -531,7 +532,7 @@ impl<'input> Decoder<'input> {
}

// Handle tuple variant
facet_core::StructKind::Tuple => {
facet_core::StructKind::Tuple if variant.data.fields.len() > 1 => {
let array_len = self.decode_array_len()?;
let field_count = variant.data.fields.len();

Expand All @@ -548,6 +549,15 @@ impl<'input> Decoder<'input> {
return Ok(());
}

// Handle wrapped type variant
facet_core::StructKind::Tuple if variant.data.fields.len() == 1 => {
wip.select_nth_variant(idx)?;
wip.begin_nth_enum_field(0)?;
self.deserialize_value(wip)?;
wip.end()?;
return Ok(());
}

// Handle struct variant
facet_core::StructKind::Struct => {
let map_len = self.decode_map_len()?;
Expand Down Expand Up @@ -676,13 +686,19 @@ impl<'input> Decoder<'input> {
}
} else if let Def::List(_list_def) = shape.def {
trace!("Deserializing list");
let array_len = self.decode_array_len()?;
wip.begin_list()?;

for _ in 0..array_len {
wip.begin_list_item()?;
self.deserialize_value(wip)?;
wip.end()?;
if self.peek_nil()? {
wip.begin_list()?;
self.decode_nil()?;
} else {
let array_len = self.decode_array_len()?;
wip.begin_list()?;

for _ in 0..array_len {
wip.begin_list_item()?;
self.deserialize_value(wip)?;
wip.end()?;
}
}
} else if let Def::Option(_option_def) = shape.def {
trace!("Deserializing option with shape: {shape}");
Expand Down
46 changes: 46 additions & 0 deletions tests/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,49 @@ fn msgpack_deserialize_struct_variant() -> Result<()> {

Ok(())
}

#[test]
fn msgpack_deserialize_struct_wrapped() -> Result<()> {
facet_testhelpers::setup();

#[derive(Facet, Debug, PartialEq)]
struct MadeIGuess {
made: String,
i: bool,
guess: i32,
}

#[derive(Facet, Debug, PartialEq)]
#[repr(u8)]
#[allow(dead_code)]
enum Point {
Thing,
Well(MadeIGuess),
Other(i32),
}

// { "Well": { "made": "in germany", "i": false, "guess": 3 } }
let data = [
0x81, // Map with 1 element
0xa4, 0x57, 0x65, 0x6c, 0x6c, // "Well"
0x83, // Map with 3 elements
0xa4, 0x6d, 0x61, 0x64, 0x65, // "made"
0xaa, 0x69, 0x6e, 0x20, 0x67, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x79, // "in germany"
0xa1, 0x69, // "i"
0xc2, // false
0xa5, 0x67, 0x75, 0x65, 0x73, 0x73, // "guess"
0x03, // 3 (positive fixint)
];

let point: Point = from_slice(&data)?;
assert_eq!(
point,
Point::Well(MadeIGuess {
made: "in germany".to_string(),
i: false,
guess: 3
})
);

Ok(())
}