From 6732d8b38a34305e0461752fc401dd97bc1e0455 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 30 May 2020 23:58:43 -0400 Subject: [PATCH 1/2] Handle nested `syn::Type:::Group` Currently, rustc does not pass the exact original TokenStream to proc-macros in several cases. This has many undesirable effects, such as losing correct location information in error message. See rust-lang/rust#43081 for more details In the future, rustc will begin passing the correct TokenStream to proc-macros. As a result, `syn` may wrap a type in one or more `syn::Type::Group`s (if the proc-macro input came from a `macro_rules!` expansion). I've determined that this can cause `yaserde-derive` to fail to match a `Type::Path`. This PR should properly handle nested groups, allowing your crate to work with both old and new input. If you have any questions, feel free to ask me. See rust-lang/rust#72622 for more details. --- yaserde_derive/src/common/field.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/yaserde_derive/src/common/field.rs b/yaserde_derive/src/common/field.rs index 1c9125e..35ecc79 100644 --- a/yaserde_derive/src/common/field.rs +++ b/yaserde_derive/src/common/field.rs @@ -225,7 +225,11 @@ impl From<&syn::Path> for Field { impl From<&syn::Field> for Field { fn from(field: &syn::Field) -> Self { - match field.ty { + let mut ty = &field.ty; + while let syn::Type::Group(g) = ty { + ty = &g.elem; + } + match ty { Path(ref path) => Field::from(&path.path), _ => panic!("unable to match {:?}", field.ty), } From 340e75cfa95a5c47ea95c46b9b2c7bf0696136c5 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Arnaud Date: Mon, 1 Jun 2020 09:45:18 +0200 Subject: [PATCH 2/2] add module unit test --- yaserde/tests/default.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/yaserde/tests/default.rs b/yaserde/tests/default.rs index c4ba308..5fadd15 100644 --- a/yaserde/tests/default.rs +++ b/yaserde/tests/default.rs @@ -110,3 +110,32 @@ fn default_attribute_string() { serialize_and_validate!(model, content); deserialize_and_validate!(content, model, XmlStruct); } + +#[test] +fn module_inclusion() { + mod module { + use super::*; + + #[derive(Debug, Default, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde(rename = "module")] + pub struct Module { + #[yaserde(attribute)] + pub color: String, + } + } + + #[derive(Debug, PartialEq, YaDeserialize, YaSerialize)] + #[yaserde(rename = "base")] + pub struct XmlStruct { + background: module::Module, + } + + let content = r#""#; + let model = XmlStruct { + background: module::Module { + color: "blue".to_string(), + }, + }; + serialize_and_validate!(model, content); + deserialize_and_validate!(content, model, XmlStruct); +}