quick-xml icon indicating copy to clipboard operation
quick-xml copied to clipboard

struct-based list can be serde-serialized as child but not as attribute

Open Kakadus opened this issue 2 months ago • 1 comments

Hi, cool project!

Consider these two types using serde (de)serialize:

use serde::{Deserialize, Serialize};

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct FooType {
    #[serde(rename = "a-list")]
    pub a_list: ListType,
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct ListType{
    #[serde(default, rename = "$text")]
    pub content: Vec<String>
}

This creates xml such as <test><a-list>A B</a-list></test>.

Now consider this slight adaptation:

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct BarType {
    #[serde(default, rename = "@a-list")]
    pub a_list: ListType,
}

I expect this to create xml such as <test a-list="A B"/>, but it fails with

Unsupported("cannot serialize struct ListType as an attribute or text content value")

I know that if I change ListType to simply

type ListType = Vec<String>

the second case works. But then, the first case does not serialize correctly: <test><a-list>A</a-list><a-list>B</a-list></test>

Is there a way to define a single ListType in such a way that both

  • <test><a-list>A B</a-list></test>
  • <test a-list="A B"/>

can be serialized? Thanks a lot!!

Kakadus avatar Oct 20 '25 23:10 Kakadus

After digging into the code a bit, I think it is possible to achieve what I want by adapting serialize_struct of the SimpleTypeSerializer to create a new SimpleSeq and writing a new impl SerializeStruct for SimpleSeq when the key is TEXT_KEY and the struct contains exactly one field. Would you be open to review a PR that implements this @Mingun?

Kakadus avatar Oct 22 '25 21:10 Kakadus