diff --git a/src/deserialize.rs b/src/deserialize.rs index 749d19b..26633bf 100644 --- a/src/deserialize.rs +++ b/src/deserialize.rs @@ -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()?; @@ -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()?; @@ -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(); @@ -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()?; @@ -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}"); diff --git a/tests/enums.rs b/tests/enums.rs index 4d158a4..a9d8540 100644 --- a/tests/enums.rs +++ b/tests/enums.rs @@ -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(()) +}