Skip to content

Commit

Permalink
Add write_serializable to writer and improve testing
Browse files Browse the repository at this point in the history
  • Loading branch information
dralley committed Jun 18, 2023
1 parent 3ab9ecc commit d30e8b2
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 30 deletions.
148 changes: 119 additions & 29 deletions src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,32 @@ impl<W: Write> Writer<W> {
start_tag: BytesStart::new(name.as_ref()),
}
}

/// Write an arbitrary serializable object
#[cfg(feature = "serialize")]
pub fn write_serializable<T: Serialize>(
&mut self,
content: &T,
) -> std::result::Result<(), DeError> {
use crate::se::Serializer;

self.write_indent()?;
let indent = self.indent.clone();
let mut fmt = ToFmtWrite(self.get_mut());
let mut serializer = Serializer::new(&mut fmt);

if let Some(indent) = indent {
serializer.indent(
indent.indent_char as char,
indent.indent_size,
indent.current_indent_len,
);
}

content.serialize(serializer)?;

Ok(())
}
}

/// A struct to write an element. Contains methods to add attributes and inner
Expand Down Expand Up @@ -358,7 +384,8 @@ impl<'a, W: Write> ElementWriter<'a, W> {
self.writer.write_indent()?;

let indent = self.writer.indent.clone();
let mut serializer = Serializer::new(ToFmtWrite(self.writer.inner()));
let fmt = &mut ToFmtWrite(self.writer.get_mut());
let mut serializer = Serializer::new(fmt);

if let Some(indent) = indent {
serializer.indent(
Expand Down Expand Up @@ -679,11 +706,20 @@ mod indentation {
}

#[cfg(feature = "serialize")]
#[test]
fn element_writer_serialize() {
mod write_serializable {
use super::*;

#[derive(Serialize)]
struct Foo {
bar: Bar,
#[serde(rename = "@attribute")]
attribute: &'static str,

element: Bar,
list: Vec<&'static str>,

#[serde(rename = "$text")]
text: &'static str,

val: String,
}

Expand All @@ -693,31 +729,85 @@ mod indentation {
bat: usize,
}

let mut buffer = Vec::new();
let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
let content = Foo {
bar: Bar { baz: 42, bat: 43 },
val: "foo".to_owned(),
};

writer
.create_element("paired")
.with_attribute(("attr1", "value1"))
.with_attribute(("attr2", "value2"))
.write_serializable_content(&content)
.expect("failure");
#[cfg(feature = "serialize")]
#[test]
fn serializable() {
let mut buffer = Vec::new();
let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);

let content = Foo {
attribute: "attribute",
element: Bar { baz: 42, bat: 43 },
list: vec!["first element", "second element"],
text: "text",
val: "foo".to_owned(),
};

let start = BytesStart::new("paired")
.with_attributes(vec![("attr1", "value1"), ("attr2", "value2")].into_iter());
let end = start.to_end();

writer
.write_event(Event::Start(start.clone()))
.expect("write start tag failed");
writer
.write_serializable(&content)
.expect("write serializable inner contents failed");
writer
.write_event(Event::End(end))
.expect("write end tag failed");

assert_eq!(
std::str::from_utf8(&buffer).unwrap(),
r#"<paired attr1="value1" attr2="value2">
<Foo attribute="attribute">
<element>
<baz>42</baz>
<bat>43</bat>
</element>
<list>first element</list>
<list>second element</list>
text
<val>foo</val>
</Foo>
</paired>"#
);
}

assert_eq!(
std::str::from_utf8(&buffer).unwrap(),
r#"<paired attr1="value1" attr2="value2">
<Foo>
<bar>
<baz>42</baz>
<bat>43</bat>
</bar>
<val>foo</val>
</Foo>
</paired>"#
);
#[test]
fn element_writer_serializable() {
let mut buffer = Vec::new();
let mut writer = Writer::new_with_indent(&mut buffer, b' ', 4);
let content = Foo {
attribute: "attribute",
element: Bar { baz: 42, bat: 43 },
list: vec!["first element", "second element"],
text: "text",
val: "foo".to_string(),
};

writer
.create_element("paired")
.with_attribute(("attr1", "value1"))
.with_attribute(("attr2", "value2"))
.write_serializable_content(&content)
.expect("failure");

assert_eq!(
std::str::from_utf8(&buffer).unwrap(),
r#"<paired attr1="value1" attr2="value2">
<Foo attribute="attribute">
<element>
<baz>42</baz>
<bat>43</bat>
</element>
<list>first element</list>
<list>second element</list>
text
<val>foo</val>
</Foo>
</paired>"#
);
}
}
}
2 changes: 1 addition & 1 deletion tests/serde-se.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ mod without_root {
fn $name() {
let mut buffer = String::new();
let mut ser = Serializer::new(&mut buffer);
ser.indent(' ', 2);
ser.indent(' ', 2, 0);

$data.serialize(ser).unwrap();
assert_eq!(buffer, $expected);
Expand Down

0 comments on commit d30e8b2

Please sign in to comment.