Skip to content

Commit

Permalink
Do not write indent before and after $text fields
Browse files Browse the repository at this point in the history
Fixes all 208 tests
  • Loading branch information
Mingun committed Oct 13, 2024
1 parent 65b9003 commit bbef94a
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 11 deletions.
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

### Bug Fixes

- [#655]: Do not write indent before and after `$text` fields and those `$value` fields
that are serialized as a text (for example, `usize` or `String`).

### Misc Changes

- [#227]: Split `SeError` from `DeError` in the `serialize` feature.
Expand All @@ -29,6 +32,7 @@
- [#820]: Classify output of the `Serializer` by returning an enumeration with kind of written data

[#227]: https://github.com/tafia/quick-xml/issues/227
[#655]: https://github.com/tafia/quick-xml/issues/655
[#810]: https://github.com/tafia/quick-xml/pull/810
[#811]: https://github.com/tafia/quick-xml/pull/811
[#820]: https://github.com/tafia/quick-xml/pull/820
Expand Down
12 changes: 4 additions & 8 deletions src/se/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ pub struct ContentSerializer<'w, 'i, W: Write> {
/// child serializers should have access to the actual state of indentation.
pub(super) indent: Indent<'i>,
/// If `true`, then current indent will be written before writing the content,
/// but only if content is not empty.
/// but only if content is not empty. This flag is reset after writing indent.
pub write_indent: bool,
// If `true`, then empty elements will be serialized as `<element></element>`
// instead of `<element/>`.
Expand All @@ -86,11 +86,7 @@ impl<'w, 'i, W: Write> ContentSerializer<'w, 'i, W> {
writer: self.writer,
target: QuoteTarget::Text,
level: self.level,
indent: if self.write_indent {
self.indent
} else {
Indent::None
},
indent: Indent::None,
}
}

Expand Down Expand Up @@ -396,8 +392,8 @@ impl<'w, 'i, W: Write> SerializeSeq for Seq<'w, 'i, W> {
T: ?Sized + Serialize,
{
self.last = value.serialize(self.ser.new_seq_element_serializer())?;
// Write indent for next element
self.ser.write_indent = true;
// Write indent for next element if indents are used
self.ser.write_indent = self.last.allow_indent();
Ok(())
}

Expand Down
17 changes: 14 additions & 3 deletions src/se/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ impl<'w, 'k, W: Write> Serializer for ElementSerializer<'w, 'k, W> {
Ok(Struct {
ser: self,
children: String::new(),
write_indent: true,
})
}

Expand Down Expand Up @@ -379,6 +380,8 @@ pub struct Struct<'w, 'k, W: Write> {
// attributes should be listed first. Fail, if attribute encountered after
// element. Use feature to configure
children: String,
/// Whether need to write indent after the last written field
write_indent: bool,
}

impl<'w, 'k, W: Write> Struct<'w, 'k, W> {
Expand Down Expand Up @@ -439,19 +442,25 @@ impl<'w, 'k, W: Write> Struct<'w, 'k, W> {
writer: &mut self.children,
level: self.ser.ser.level,
indent: self.ser.ser.indent.borrow(),
write_indent: true,
// If previous field does not require indent, do not write it
write_indent: self.write_indent,
expand_empty_elements: self.ser.ser.expand_empty_elements,
};

if key == TEXT_KEY {
value.serialize(TextSerializer(ser.into_simple_type_serializer()))?;
// Text was written so we don't need to indent next field
self.write_indent = false;
} else if key == VALUE_KEY {
value.serialize(ser)?;
// If element was written then we need to indent next field unless it is a text field
self.write_indent = value.serialize(ser)?.allow_indent();
} else {
value.serialize(ElementSerializer {
key: XmlName::try_from(key)?,
ser,
})?;
// Element was written so we need to indent next field unless it is a text field
self.write_indent = true;
}
Ok(())
}
Expand Down Expand Up @@ -483,7 +492,9 @@ impl<'w, 'k, W: Write> SerializeStruct for Struct<'w, 'k, W> {
self.ser.ser.writer.write_char('>')?;
self.ser.ser.writer.write_str(&self.children)?;

self.ser.ser.indent.write_indent(&mut self.ser.ser.writer)?;
if self.write_indent {
self.ser.ser.indent.write_indent(&mut self.ser.ser.writer)?;
}

self.ser.ser.writer.write_str("</")?;
self.ser.ser.writer.write_str(self.ser.key.0)?;
Expand Down
8 changes: 8 additions & 0 deletions src/se/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,14 @@ pub enum WriteResult {
SensitiveNothing,
}

impl WriteResult {
/// Returns `true` if indent should be written after the object (if configured) and `false` otherwise.
#[inline]
pub fn allow_indent(&self) -> bool {
matches!(self, Self::Element | Self::Nothing)
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////

/// Implements serialization method by forwarding it to the serializer created by
Expand Down

0 comments on commit bbef94a

Please sign in to comment.