Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions avro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down
81 changes: 81 additions & 0 deletions avro/src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Comment on lines +552 to +554
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The clear method in the impl Clearable for Vec<u8> is calling itself, which will lead to infinite recursion and a stack overflow. You should call the clear method from Vec<u8> instead to avoid this.

Suggested change
fn clear(&mut self) {
self.clear();
}
fn clear(&mut self) {
Vec::clear(self);
}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value:annoying; category:bug; feedback: The Gemini AI reviewer is not correct! The code works fine because the Rust compiler prefers inherent methods over trait methods. The code does look confusing, so using Vec::clear(self) would improve the maintainablity!

Comment on lines +551 to +554
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

self.clear() in impl Clearable for Vec<u8> looks like infinite recursion.

While not actually recursive — Rust's method resolution gives inherent methods priority over trait methods, so self.clear() dispatches to Vec::clear() — this is visually indistinguishable from a recursive call and is a maintenance hazard: any future type that implements Clearable with a same-named inherent method removed, or a naive copy of this pattern for a type without an inherent clear, will recurse infinitely.

Use the fully-qualified inherent call to make the intent unambiguous:

🐛 Proposed fix
 impl Clearable for Vec<u8> {
     fn clear(&mut self) {
-        self.clear();
+        Vec::clear(self);
     }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
impl Clearable for Vec<u8> {
fn clear(&mut self) {
self.clear();
}
impl Clearable for Vec<u8> {
fn clear(&mut self) {
Vec::clear(self);
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@avro/src/writer.rs` around lines 551 - 554, In the impl Clearable for Vec<u8>
the call self.clear() is ambiguous and visually looks recursive; change it to
invoke the Vec inherent method explicitly by replacing self.clear() with the
fully-qualified inherent call <Vec<u8>>::clear(self) inside the impl Clearable
for Vec<u8>::fn clear to make the intent unambiguous and avoid potential
recursion hazards.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value:good-to-have; category:bug; feedback: The CodeRabbit AI reviewer is correct! The code does look confusing, so using Vec::clear(self) would improve the maintainability!

}

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)?;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The example for the new reset method uses writer.append(), which is deprecated. Please use writer.append_value() for consistency with the rest of the example and to avoid promoting the use of deprecated APIs.

Suggested change
/// writer.append(value)?;
/// writer.append_value(value)?;

Copy link
Copy Markdown
Owner Author

@martin-augment martin-augment Feb 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value:good-to-have; category:documentation; feedback: The Gemini AI reviewer is correct! The Writer::append() method is deprecated, so the docstring should use its replacement - Writer::append_value().

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example uses writer.append(value)?;, but append is deprecated in favor of append_value (which the snippet already uses earlier). Consider using append_value here as well to keep the example consistent and avoid deprecation warnings in doctests.

Severity: low

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Copy link
Copy Markdown
Owner Author

@martin-augment martin-augment Feb 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value:good-to-have; category:documentation; feedback: The Augment AI reviewer is correct! The Writer::append() method is deprecated, so the docstring should use its replacement - Writer::append_value().

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Doc example calls deprecated writer.append() — use writer.append_value() instead.

Writer::append has been deprecated since 0.22.0 in favour of append_value. Using it in a doc test will produce a deprecation warning (potentially an error if the crate's lint config escalates it).

📝 Proposed fix
-    ///     writer.append(value)?;
+    ///     writer.append_value(value)?;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// writer.append(value)?;
/// writer.append_value(value)?;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@avro/src/writer.rs` at line 585, The doc example currently calls the
deprecated Writer::append; update the example to call Writer::append_value
instead to avoid deprecation warnings. Locate the doc snippet that shows
writer.append(value)? and replace that invocation with
writer.append_value(value)? (keeping the same error handling and context), and
ensure any imports or trait bounds referenced in the example still apply to
append_value.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value:good-to-have; category:documentation; feedback: The CodeRabbit AI reviewer is correct! The Writer::append() method is deprecated, so the docstring should use its replacement - 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) {
Expand Down Expand Up @@ -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(())
}
}