RReverser / serde-xml-rs

xml-rs based deserializer for Serde (compatible with 1.0+)
https://crates.io/crates/serde-xml-rs
MIT License
269 stars 90 forks source link

Wrong serialization of Vec<Enum> #184

Open aknarts opened 2 years ago

aknarts commented 2 years ago

I am trying to serialize this

#[derive(Serialize)]
pub struct Test {
    pub val: Vec<TestEnum>,
}

#[derive(Serialize)]
pub enum TestEnum {
    #[serde(rename_all = "camelCase")]
    FirstEnum {
        content: String
    },
    #[serde(rename_all = "camelCase")]
    SecondEnum {
        cont: String
    },
}

let mut test = Test { val: vec![] };
test.val.push(TestEnum::FirstEnum { content: "Test1".to_string() });
test.val.push(TestEnum::SecondEnum { cont: "Test2".to_string() });
println!("{}", serde_xml_rs::to_string(&test).unwrap());

Sadly this ends up being

<?xml version="1.0" encoding="UTF-8"?>
<Test>
    <val>
        <FirstEnum>
            <content>Test1</content>
        </FirstEnum>
    </val>
    <content>
        <SecondEnum>
            <cont>Test2</cont>
        </SecondEnum>
    </content>
</Test>

I think the expected output would be

<?xml version="1.0" encoding="UTF-8"?>
<Test>
    <val>
        <FirstEnum>
            <content>Test1</content>
        </FirstEnum>
        <SecondEnum>
            <cont>Test2</cont>
        </SecondEnum>
    </val>
</Test>

Or am I doing something wrong here?

aknarts commented 2 years ago

I did identify where the wrong tag comes in https://github.com/RReverser/serde-xml-rs/blob/master/src/ser/seq.rs#L26-L29 which closes the </val> after the first enum and then the next call to build_start_tag() opens <content> because that is the curent_tag

And that is it from me, somebody way more knowledgeable than me in this matter has got to figure this one out. Trying to look into how serde_json does it makes my head hurt.

aknarts commented 2 years ago

Not sure if this helps

[2022-09-09T20:17:47Z DEBUG serde_xml_rs::ser] Struct Test
[2022-09-09T20:17:47Z DEBUG serde_xml_rs::ser::map] field val
[2022-09-09T20:17:47Z DEBUG serde_xml_rs::ser] Sequence
[2022-09-09T20:17:47Z DEBUG serde_xml_rs::ser] Struct variant FirstEnum
[2022-09-09T20:17:47Z DEBUG serde_xml_rs::ser::map] field content
[2022-09-09T20:17:47Z DEBUG serde_xml_rs::ser::map] end field
[2022-09-09T20:17:47Z DEBUG serde_xml_rs::ser] Struct variant SecondEnum
[2022-09-09T20:17:47Z DEBUG serde_xml_rs::ser::map] field cont
[2022-09-09T20:17:47Z DEBUG serde_xml_rs::ser::map] end field
[2022-09-09T20:17:47Z DEBUG serde_xml_rs::ser::map] end field