io: Introduce decode_from_read_with function
What changed, and why it matters
This commit adds a new helper function to the rust-bitcoin library that lets developers decode data from a reader using any decoder type that can be created with default settings. It is a pure API addition: it refactors an existing function into a shared internal helper and exposes a new public entry point. There is no bug fix, behavior change, or security-related content in the diff.
No security action required. Treat as a normal API enhancement.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change introduces decode_from_read_with<D, R>() in io/src/lib.rs, which is generic over D: Decoder + Default rather than T: Decode. The existing decode_from_read<T, R>() is rewritten to call a new private decode_from_read_internal() with T::decoder(). The internal function contains the original decode loop. No logic changes; this is a refactor to expose a more flexible public API for decoders without a dedicated Decode implementer.
Changed components
io/src/lib.rsdecode_from_readdecode_from_read_withInspect captured patch +36 / −2
diff --git a/io/src/lib.rs b/io/src/lib.rs
index da50f544..dfd3f3c5 100644
--- a/io/src/lib.rs
+++ b/io/src/lib.rs
@@ -501,14 +501,48 @@ where
/// Returns [`ReadError::Decode`] if the decoder encounters an error while parsing
/// the data, or [`ReadError::Io`] if an I/O error occurs while reading.
pub fn decode_from_read<T, R>(
- mut reader: R,
+ reader: R,
) -> core::result::Result<T, ReadError<<T::Decoder as Decoder>::Error>>
where
T: Decode,
R: BufRead,
{
- let mut decoder = T::decoder();
+ decode_from_read_internal(reader, T::decoder())
+}
+
+/// Decodes an object from a buffered reader using a [`Decoder`] type.
+///
+/// Unlike [`decode_from_read`], this takes a generic [`Decoder`] parameter, allowing use with
+/// decoders which don't have a dedicated [`Decode`] implementer.
+///
+/// # Performance
+///
+/// For unbuffered readers (like [`std::fs::File`] or [`std::net::TcpStream`]), consider wrapping
+/// your reader with [`std::io::BufReader`] in order to use this function. This avoids frequent
+/// small reads, which can significantly impact performance.
+///
+/// # Errors
+///
+/// Returns [`ReadError::Decode`] if the decoder encounters an error while parsing
+/// the data, or [`ReadError::Io`] if an I/O error occurs while reading.
+pub fn decode_from_read_with<D, R>(
+ reader: R,
+) -> core::result::Result<D::Output, ReadError<D::Error>>
+where
+ D: Decoder + Default,
+ R: BufRead,
+{
+ decode_from_read_internal(reader, D::default())
+}
+fn decode_from_read_internal<D, R>(
+ mut reader: R,
+ mut decoder: D,
+) -> core::result::Result<D::Output, ReadError<D::Error>>
+where
+ D: Decoder + Default,
+ R: BufRead,
+{
loop {
let mut buffer = match reader.fill_buf() {
Ok(buffer) => buffer,
Why this scored 16/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.