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

Keep specific element to single line while using indent with serde serializer

Open ShaddyDC opened this issue 1 year ago • 1 comments

Hi, thanks for making this library; I'm getting a lot of use out of it. However, I've run into an issue where I have to format some code a certain way that a proprietary reader expects it to be. Namely, I've got these structures:

#[derive(Deserialize, Serialize, Debug)]
pub struct TextureCoordinates {
    #[serde(rename = "@dimension")]
    pub dimension: String,
    #[serde(rename = "@channel")]
    pub channel: String,
    #[serde(rename = "$value")]
    pub elements: String,
}
#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "PascalCase")]
pub struct VertexBuffer {
    pub positions: String,
    pub normals: String,
    #[serde(skip_serializing_if = "Option::is_none", default)]
    pub texture_coordinates: Option<TextureCoordinates>,
}

I'm writing like this, though admittedly with some context missing:

let mut ser = Serializer::with_root(&mut buffer, None).unwrap();
ser.indent(' ', 2);
ser.expand_empty_elements(true);

obj.serialize(ser).unwrap();

The texture coordinates serialise to something like this:

<VertexBuffer>
  <Positions>319.066 -881.28705 7.71589</Positions>
  <Normals>-0.0195154 -0.21420999 0.976593</Normals>
  <TextureCoordinates dimension="2D" channel="0">
    0.752494 0.201033,0.773967 0.201033
  </TextureCoordinates>
</VertexBuffer>

However, the program I need to serialize for requires this format instead:

<VertexBuffer>
  <Positions>319.066 -881.28705 7.71589</Positions>
  <Normals>-0.0195154 -0.21420999 0.976593</Normals>
  <TextureCoordinates dimension="2D" channel="0">752494 0.201033,0.773967 0.201033</TextureCoordinates>
</VertexBuffer>

Is there some way to achieve this that I'm not aware of?

I'm currently working around it by just not using indentation, so everything is written in a single line, but it would be nice to have.

ShaddyDC avatar Sep 21 '23 09:09 ShaddyDC

The difference between Positions and TextureCoordinates is that the first is a (serde) primitive type, while the second is a struct, which potentially can have other elements inside. But in this specific case we a able to inspect all fields of the serialized struct understand that all of them are attributes and do not make indent for them.

Anyway, writing of struct content is buffered, so we should be able to understand if intendation is needed or not and apply it if required.

I would happy to merge a PR that do that.

Mingun avatar Sep 21 '23 11:09 Mingun