This is an automated email from the ASF dual-hosted git repository. kriskras99 pushed a commit to branch feat/resetable_writer in repository https://gitbox.apache.org/repos/asf/avro-rs.git
commit 1e2d1270415414ea794799fde45b6a1eeac813c5 Author: Kriskras99 <[email protected]> AuthorDate: Wed Feb 18 14:48:42 2026 +0000 feat: Add support for resetting a Writer back by a clearable buffer --- avro/src/lib.rs | 4 +-- avro/src/writer.rs | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/avro/src/lib.rs b/avro/src/lib.rs index 739c5b5..d166c51 100644 --- a/avro/src/lib.rs +++ b/avro/src/lib.rs @@ -98,8 +98,8 @@ pub use schema::Schema; pub use serde::{AvroSchema, AvroSchemaComponent, from_value, to_value}; pub use uuid::Uuid; pub use writer::{ - GenericSingleObjectWriter, SpecificSingleObjectWriter, Writer, WriterBuilder, to_avro_datum, - to_avro_datum_schemata, write_avro_datum_ref, + Clearable, GenericSingleObjectWriter, SpecificSingleObjectWriter, Writer, WriterBuilder, + to_avro_datum, to_avro_datum_schemata, write_avro_datum_ref, }; #[cfg(feature = "derive")] diff --git a/avro/src/writer.rs b/avro/src/writer.rs index c8e02c8..45a67b6 100644 --- a/avro/src/writer.rs +++ b/avro/src/writer.rs @@ -542,6 +542,60 @@ impl<'a, W: Write> Writer<'a, W> { } } +/// A buffer that can be cleared. +pub trait Clearable { + /// Clear the buffer, keeping the capacity. + fn clear(&mut self); +} + +impl Clearable for Vec<u8> { + fn clear(&mut self) { + self.clear(); + } +} + +impl<'a, W: Clearable + Write> Writer<'a, W> { + /// Reset the writer. + /// + /// This will clear the underlying writer and the internal buffer. + /// It will also clear any user metadata added. + /// + /// # Example + /// ``` + /// # use apache_avro::{Writer, Schema, Error}; + /// # let schema = Schema::Boolean; + /// # let values = [true, false]; + /// # fn send(_: &Vec<u8>) {} + /// let mut writer = Writer::new(&schema, Vec::new())?; + /// + /// // Write some values + /// for value in values { + /// writer.append_value(value)?; + /// } + /// + /// // Flush the buffer and only then do something with buffer + /// writer.flush()?; + /// send(writer.get_ref()); + /// + /// // Reset the writer + /// writer.reset(); + /// + /// // Write some values again + /// for value in values { + /// writer.append(value)?; + /// } + /// + /// # Ok::<(), Error>(()) + /// ``` + pub fn reset(&mut self) { + self.buffer.clear(); + self.writer.clear(); + self.has_header = false; + self.num_values = 0; + self.user_metadata.clear(); + } +} + impl<W: Write> Drop for Writer<'_, W> { /// Drop the writer, will try to flush ignoring any errors. fn drop(&mut self) { @@ -1858,4 +1912,31 @@ mod tests { Ok(()) } + + #[test] + fn avro_rs_469_reset_writer() -> TestResult { + let schema = Schema::Boolean; + let values = [true, false, true, false]; + let mut writer = Writer::new(&schema, Vec::new())?; + + for value in values { + writer.append_value(value)?; + } + + writer.flush()?; + let first_buffer = writer.get_ref().clone(); + + writer.reset(); + assert_eq!(writer.get_ref().len(), 0); + + for value in values { + writer.append_value(value)?; + } + + writer.flush()?; + let second_buffer = writer.get_ref().clone(); + assert_eq!(first_buffer, second_buffer); + + Ok(()) + } }
