Skip to content

Commit

Permalink
Consume event when write. Use Event::borrow() if you want to keep o…
Browse files Browse the repository at this point in the history
…wnership

This change will allow to feed to the writer different structs which, otherwise,
would be impossible if are not holds an `Event` inside your struct. In the future
the Event may be split into `reader::Event` and `writer::Event` and the reader
variant may evolve to be borrow-only.
  • Loading branch information
Mingun committed Jun 16, 2024
1 parent c0280cd commit 9fc1bb0
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 34 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
- `Writer::new()`
- [#760]: `Attribute::decode_and_unescape_value` and `Attribute::decode_and_unescape_value_with` now
accepts `Decoder` instead of `Reader`. Use `Reader::decoder()` to get it.
- [#760]: `Writer::write_event` now consumes event. Use `Event::borrow()` if you want to keep ownership.

[#650]: https://github.com/tafia/quick-xml/issues/650
[#755]: https://github.com/tafia/quick-xml/pull/755
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/fuzz_target_1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ where
let _event = black_box(event.borrow());
let _event = black_box(event.as_ref());
debug_format!(event);
debug_format!(writer.write_event(event));
debug_format!(writer.write_event(event.borrow()));
}
match event_result {
Ok(Event::Start(ref e)) | Ok(Event::Empty(ref e)) => {
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/structured_roundtrip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn fuzz_round_trip(driver: Driver) -> quick_xml::Result<()> {
// TODO: Handle error cases.
use WriterFunc::*;
match writer_func {
WriteEvent(event) => writer.write_event(event)?,
WriteEvent(event) => writer.write_event(event.borrow())?,
WriteBom => writer.write_bom()?,
WriteIndent => writer.write_indent()?,
CreateElement {
Expand Down
32 changes: 16 additions & 16 deletions src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use {crate::de::DeError, serde::Serialize};
/// },
/// Ok(Event::Eof) => break,
/// // we can either move or borrow the event to write, depending on your use-case
/// Ok(e) => assert!(writer.write_event(e).is_ok()),
/// Ok(e) => assert!(writer.write_event(e.borrow()).is_ok()),
/// Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
/// }
/// }
Expand Down Expand Up @@ -193,37 +193,37 @@ impl<W: Write> Writer<W> {
}

/// Writes the given event to the underlying writer.
pub fn write_event<'a, E: AsRef<Event<'a>>>(&mut self, event: E) -> Result<()> {
pub fn write_event<'a, E: Into<Event<'a>>>(&mut self, event: E) -> Result<()> {
let mut next_should_line_break = true;
let result = match *event.as_ref() {
Event::Start(ref e) => {
let result = self.write_wrapped(b"<", e, b">");
let result = match event.into() {
Event::Start(e) => {
let result = self.write_wrapped(b"<", &e, b">");
if let Some(i) = self.indent.as_mut() {
i.grow();
}
result
}
Event::End(ref e) => {
Event::End(e) => {
if let Some(i) = self.indent.as_mut() {
i.shrink();
}
self.write_wrapped(b"</", e, b">")
self.write_wrapped(b"</", &e, b">")
}
Event::Empty(ref e) => self.write_wrapped(b"<", e, b"/>"),
Event::Text(ref e) => {
Event::Empty(e) => self.write_wrapped(b"<", &e, b"/>"),
Event::Text(e) => {
next_should_line_break = false;
self.write(e)
self.write(&e)
}
Event::Comment(ref e) => self.write_wrapped(b"<!--", e, b"-->"),
Event::CData(ref e) => {
Event::Comment(e) => self.write_wrapped(b"<!--", &e, b"-->"),
Event::CData(e) => {
next_should_line_break = false;
self.write(b"<![CDATA[")?;
self.write(e)?;
self.write(&e)?;
self.write(b"]]>")
}
Event::Decl(ref e) => self.write_wrapped(b"<?", e, b"?>"),
Event::PI(ref e) => self.write_wrapped(b"<?", e, b"?>"),
Event::DocType(ref e) => self.write_wrapped(b"<!DOCTYPE ", e, b">"),
Event::Decl(e) => self.write_wrapped(b"<?", &e, b"?>"),
Event::PI(e) => self.write_wrapped(b"<?", &e, b"?>"),
Event::DocType(e) => self.write_wrapped(b"<!DOCTYPE ", &e, b">"),
Event::Eof => Ok(()),
};
if let Some(i) = self.indent.as_mut() {
Expand Down
30 changes: 15 additions & 15 deletions src/writer/async_tokio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,37 @@ use crate::{ElementWriter, Writer};

impl<W: AsyncWrite + Unpin> Writer<W> {
/// Writes the given event to the underlying writer. Async version of [`Writer::write_event`].
pub async fn write_event_async<'a, E: AsRef<Event<'a>>>(&mut self, event: E) -> Result<()> {
pub async fn write_event_async<'a, E: Into<Event<'a>>>(&mut self, event: E) -> Result<()> {
let mut next_should_line_break = true;
let result = match *event.as_ref() {
Event::Start(ref e) => {
let result = self.write_wrapped_async(b"<", e, b">").await;
let result = match event.into() {
Event::Start(e) => {
let result = self.write_wrapped_async(b"<", &e, b">").await;
if let Some(i) = self.indent.as_mut() {
i.grow();
}
result
}
Event::End(ref e) => {
Event::End(e) => {
if let Some(i) = self.indent.as_mut() {
i.shrink();
}
self.write_wrapped_async(b"</", e, b">").await
self.write_wrapped_async(b"</", &e, b">").await
}
Event::Empty(ref e) => self.write_wrapped_async(b"<", e, b"/>").await,
Event::Text(ref e) => {
Event::Empty(e) => self.write_wrapped_async(b"<", &e, b"/>").await,
Event::Text(e) => {
next_should_line_break = false;
self.write_async(e).await
self.write_async(&e).await
}
Event::Comment(ref e) => self.write_wrapped_async(b"<!--", e, b"-->").await,
Event::CData(ref e) => {
Event::Comment(e) => self.write_wrapped_async(b"<!--", &e, b"-->").await,
Event::CData(e) => {
next_should_line_break = false;
self.write_async(b"<![CDATA[").await?;
self.write_async(e).await?;
self.write_async(&e).await?;
self.write_async(b"]]>").await
}
Event::Decl(ref e) => self.write_wrapped_async(b"<?", e, b"?>").await,
Event::PI(ref e) => self.write_wrapped_async(b"<?", e, b"?>").await,
Event::DocType(ref e) => self.write_wrapped_async(b"<!DOCTYPE ", e, b">").await,
Event::Decl(e) => self.write_wrapped_async(b"<?", &e, b"?>").await,
Event::PI(e) => self.write_wrapped_async(b"<?", &e, b"?>").await,
Event::DocType(e) => self.write_wrapped_async(b"<!DOCTYPE ", &e, b">").await,
Event::Eof => Ok(()),
};
if let Some(i) = self.indent.as_mut() {
Expand Down
2 changes: 1 addition & 1 deletion tests/unit_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ fn test_writer_borrow() -> Result<()> {
loop {
match reader.read_event()? {
Eof => break,
e => assert!(writer.write_event(&e).is_ok()), // either `e` or `&e`
e => assert!(writer.write_event(e.borrow()).is_ok()),
}
}

Expand Down

0 comments on commit 9fc1bb0

Please sign in to comment.