diff --git a/Changelog.md b/Changelog.md
index 8d71aeb6..a0bfeeeb 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -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.
@@ -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
diff --git a/src/se/content.rs b/src/se/content.rs
index e814f5b9..6c867426 100644
--- a/src/se/content.rs
+++ b/src/se/content.rs
@@ -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 ``
// instead of ``.
@@ -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,
}
}
@@ -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(())
}
diff --git a/src/se/element.rs b/src/se/element.rs
index 10a62389..1ea17194 100644
--- a/src/se/element.rs
+++ b/src/se/element.rs
@@ -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,
})
}
@@ -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> {
@@ -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(())
}
@@ -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)?;
diff --git a/src/se/mod.rs b/src/se/mod.rs
index 3e84534d..db2f8bbb 100644
--- a/src/se/mod.rs
+++ b/src/se/mod.rs
@@ -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