Skip to content

Commit 7d3b641

Browse files
committed
Fix untagged vec
1 parent 9c52713 commit 7d3b641

File tree

4 files changed

+37
-10
lines changed

4 files changed

+37
-10
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
authors = ["ImJeremyHe<yiliang.he@qq.com>"]
33
edition = "2018"
44
name = "xmlserde"
5-
version = "0.10.1"
5+
version = "0.10.2"
66
license = "MIT"
77
description = "useful tool for serializing and deserializing xml"
88
repository = "https://github.com/ImJeremyHe/xmlserde"

derives/src/container.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ impl<'a> StructField<'a> {
244244
}
245245

246246
pub fn is_required(&self) -> bool {
247-
if matches!(self.ty, EleType::Untag) {
247+
if matches!(self.ty, EleType::Untag) || matches!(self.ty, EleType::UntaggedEnum) {
248248
return match self.generic {
249249
Generic::Vec(_) => false,
250250
Generic::Opt(_) => false,

derives/src/de.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,24 @@ pub fn get_de_struct_impl_block(container: Container) -> proc_macro2::TokenStrea
140140
untagged_enums,
141141
untagged_structs,
142142
} = summary;
143-
let get_children_tags = if children.len() > 0 {
143+
let get_children_tags = if children.len() > 0 || untagged_enums.len() > 0 {
144144
let names = children.iter().map(|f| {
145145
let n = f.name.as_ref().expect("should have name");
146146
quote! {#n}
147147
});
148+
let untagged_enums = untagged_enums.iter().map(|f| {
149+
let ty = match &f.generic {
150+
Generic::Vec(t) => t,
151+
Generic::Opt(t) => t,
152+
Generic::None => &f.original.ty,
153+
};
154+
quote! {#ty::__get_children_tags()}
155+
});
148156
quote! {
149157
fn __get_children_tags() -> Vec<&'static [u8]> {
150-
vec![#(#names,)*]
158+
let mut r: Vec<&'static [u8]> = vec![#(#names,)*];
159+
#(r.extend(#untagged_enums.into_iter());)*
160+
r
151161
}
152162
}
153163
} else {
@@ -179,11 +189,12 @@ pub fn get_de_struct_impl_block(container: Container) -> proc_macro2::TokenStrea
179189
};
180190

181191
// Only those structs with only children can be untagged
182-
let deserialize_from_unparsed = if children.len() > 0 && attr_len == 0 && sfc_len == 0 {
183-
get_deserialize_from_unparsed(&children)
184-
} else {
185-
quote! {}
186-
};
192+
let deserialize_from_unparsed =
193+
if children.len() > 0 && attr_len == 0 && sfc_len == 0 && untagged_enums.len() == 0 {
194+
get_deserialize_from_unparsed(&children)
195+
} else {
196+
quote! {}
197+
};
187198
let encounter_unknown = if container.deny_unknown {
188199
quote! {
189200
let _field = std::str::from_utf8(_field).unwrap();
@@ -264,7 +275,7 @@ fn get_untagged_struct_fields_result(fileds: &[StructField]) -> proc_macro2::Tok
264275
match f.generic {
265276
Generic::Vec(_) => unreachable!(),
266277
Generic::Opt(_t) => quote! {
267-
if #ident_opt_unparsed_array .len() > 0 {
278+
if #ident_opt_unparsed_array.len() > 0 {
268279
#ident = Some(#_t::__deserialize_from_unparsed_array(#ident_opt_unparsed_array));
269280
}
270281
},

tests/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,4 +836,20 @@ mod tests {
836836
#[derive(Clone, Debug, Default, XmlDeserialize)]
837837
pub struct A {}
838838
}
839+
840+
#[test]
841+
fn test_vec_deserialize() {
842+
#[derive(Debug, XmlDeserialize)]
843+
pub struct CtTextParagraph {
844+
#[xmlserde(name = b"pPr", ty = "child")]
845+
pub _p_pr: Option<CtTextParagraphProperties>,
846+
#[xmlserde(ty = "untagged_enum")]
847+
pub _text_runs: Vec<A>,
848+
}
849+
850+
#[derive(Debug, XmlDeserialize, XmlSerialize)]
851+
pub struct A {}
852+
#[derive(Debug, XmlDeserialize, XmlSerialize)]
853+
pub struct CtTextParagraphProperties {}
854+
}
839855
}

0 commit comments

Comments
 (0)