How to flatten a `Vec` field when serializing a struct with serde?

谁都会走 提交于 2021-01-29 04:45:22

问题


I've got some XML that has a tag containing multiple sibling tags with the same name, like so:

<foo>
    <bar/>
    <bar/>
</foo>

(There may also be multiple top level <foo>s as well, though I've not gotten around to trying to (de)serialize that yet.)

Using this code:

use serde::{Deserialize, Serialize};
use quick_xml::de::from_str;
use quick_xml::se::to_string;

#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct Foo {
    #[serde(rename = "bar", default)]
    bars: Vec<Bar>,
}

#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[serde(rename = "bar")]
struct Bar{

}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn deserialize_trivial_string_test() {
        let fs = "<foo><bar/><bar/></foo>";
        let foo = from_str(fs).unwrap();
        assert_eq!(Foo { bars: vec![Bar {}, Bar {}] }, foo);
    }

    #[test]
    fn serialize_trivial_string_test() {
        let foo = Foo { bars: vec![Bar {}, Bar {}] };
        let fs = to_string(&foo).unwrap();
        assert_eq!("<foo><bar/><bar/></foo>", fs);
    }
}

and don't forget to activate serialize feature:

[dependencies.quick-xml]
version = "0.18.1"
features = ["serialize"]

I can deserialize just fine, but serialization adds in an extra <bar> tag as the bars field wrapping the actual <bar> tags:

<Foo>
    <bar>
        <bar></bar>
        <bar></bar>
    </bar>
</Foo>

The #[serde(rename = "bar", default)] on the bars field was my first attempt to fix the this, based on quick-xml's documentation, but it obviously does not work. I also looked through serde's documentation, and did find a flatten attribute, but it did not seem to work when I tried applying it to the bars field.

Is there any way to get the serialization that I need, short of manually implementing Deserialize?

In case it's relevant, the actual data format I'm trying to work with is the flam3 file format. There's a sample file here. The <flame> element would be the equivalent to <foo> here, and <xform> is equivalent to <bar>.


回答1:


Unfortunately you can't. There is a outstanding issue on GitHub that addresses your question.



来源:https://stackoverflow.com/questions/62363984/how-to-flatten-a-vec-field-when-serializing-a-struct-with-serde

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!