From 9fc1bb0af78e98c95c9c24d5fb7d8166a36da3d5 Mon Sep 17 00:00:00 2001 From: Mingun Date: Sun, 10 Jul 2022 01:21:23 +0500 Subject: [PATCH] Consume event when write. Use `Event::borrow()` if you want to keep ownership 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. --- Changelog.md | 1 + fuzz/fuzz_targets/fuzz_target_1.rs | 2 +- fuzz/fuzz_targets/structured_roundtrip.rs | 2 +- src/writer.rs | 32 +++++++++++------------ src/writer/async_tokio.rs | 30 ++++++++++----------- tests/unit_tests.rs | 2 +- 6 files changed, 35 insertions(+), 34 deletions(-) diff --git a/Changelog.md b/Changelog.md index 58aad0cd..fb294607 100644 --- a/Changelog.md +++ b/Changelog.md @@ -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 diff --git a/fuzz/fuzz_targets/fuzz_target_1.rs b/fuzz/fuzz_targets/fuzz_target_1.rs index 9809526f..08d983e9 100644 --- a/fuzz/fuzz_targets/fuzz_target_1.rs +++ b/fuzz/fuzz_targets/fuzz_target_1.rs @@ -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)) => { diff --git a/fuzz/fuzz_targets/structured_roundtrip.rs b/fuzz/fuzz_targets/structured_roundtrip.rs index 2eb6962e..6432cb95 100644 --- a/fuzz/fuzz_targets/structured_roundtrip.rs +++ b/fuzz/fuzz_targets/structured_roundtrip.rs @@ -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 { diff --git a/src/writer.rs b/src/writer.rs index a1b6fa85..a2236a0c 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -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), /// } /// } @@ -193,37 +193,37 @@ impl Writer { } /// Writes the given event to the underlying writer. - pub fn write_event<'a, E: AsRef>>(&mut self, event: E) -> Result<()> { + pub fn write_event<'a, E: Into>>(&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"") + self.write_wrapped(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""), - Event::CData(ref e) => { + Event::Comment(e) => self.write_wrapped(b""), + Event::CData(e) => { next_should_line_break = false; self.write(b"") } - Event::Decl(ref e) => self.write_wrapped(b""), - Event::PI(ref e) => self.write_wrapped(b""), - Event::DocType(ref e) => self.write_wrapped(b""), + Event::Decl(e) => self.write_wrapped(b""), + Event::PI(e) => self.write_wrapped(b""), + Event::DocType(e) => self.write_wrapped(b""), Event::Eof => Ok(()), }; if let Some(i) = self.indent.as_mut() { diff --git a/src/writer/async_tokio.rs b/src/writer/async_tokio.rs index dfecbe4a..dab4c5b2 100644 --- a/src/writer/async_tokio.rs +++ b/src/writer/async_tokio.rs @@ -9,37 +9,37 @@ use crate::{ElementWriter, Writer}; impl Writer { /// Writes the given event to the underlying writer. Async version of [`Writer::write_event`]. - pub async fn write_event_async<'a, E: AsRef>>(&mut self, event: E) -> Result<()> { + pub async fn write_event_async<'a, E: Into>>(&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"").await + self.write_wrapped_async(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"").await, - Event::CData(ref e) => { + Event::Comment(e) => self.write_wrapped_async(b"").await, + Event::CData(e) => { next_should_line_break = false; self.write_async(b"").await } - Event::Decl(ref e) => self.write_wrapped_async(b"").await, - Event::PI(ref e) => self.write_wrapped_async(b"").await, - Event::DocType(ref e) => self.write_wrapped_async(b"").await, + Event::Decl(e) => self.write_wrapped_async(b"").await, + Event::PI(e) => self.write_wrapped_async(b"").await, + Event::DocType(e) => self.write_wrapped_async(b"").await, Event::Eof => Ok(()), }; if let Some(i) = self.indent.as_mut() { diff --git a/tests/unit_tests.rs b/tests/unit_tests.rs index 954b90a2..4114847e 100644 --- a/tests/unit_tests.rs +++ b/tests/unit_tests.rs @@ -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()), } }