pub struct Counter<D> { /* private fields */ }Expand description
A wrapper that adds byte counting functionality to any reader, writer, or seeker.
Counter<D> tracks the total number of bytes read from and written to the underlying
I/O object, providing methods to query these statistics at any time.
§Type Parameter
D- The underlying I/O object (reader, writer, or seeker)
§Examples
§Basic Usage with std::io
use std::io::{Read, Write};
use countio::Counter;
// Counting bytes read
let data = b"Hello, World!";
let mut reader = Counter::new(&data[..]);
let mut buffer = [0u8; 5];
reader.read(&mut buffer).unwrap();
assert_eq!(reader.reader_bytes(), 5);
// Counting bytes written
let mut writer = Counter::new(Vec::new());
writer.write_all(b"Hello").unwrap();
assert_eq!(writer.writer_bytes(), 5);§With Buffered I/O
use std::io::{BufRead, BufReader, BufWriter, Write};
use countio::Counter;
// Buffered reading
let data = "Line 1\nLine 2\nLine 3\n";
let reader = BufReader::new(data.as_bytes());
let mut counter = Counter::new(reader);
let mut line = String::new();
counter.read_line(&mut line).unwrap();
assert_eq!(counter.reader_bytes(), 7);
// Buffered writing
let writer = BufWriter::new(Vec::new());
let mut counter = Counter::new(writer);
counter.write_all(b"Hello, World!").unwrap();
counter.flush().unwrap();
assert_eq!(counter.writer_bytes(), 13);§Performance
The overhead of byte counting is minimal - just an integer addition per I/O operation.
The wrapper implements all relevant traits (Read, Write, Seek, etc.) by
delegating to the inner object while tracking byte counts.
Implementations§
Source§impl<D> Counter<D>
impl<D> Counter<D>
Sourcepub const fn new(inner: D) -> Self
pub const fn new(inner: D) -> Self
Creates a new Counter<D> wrapping the given I/O object with zero read/written bytes.
§Arguments
inner- The I/O object to wrap (reader, writer, seeker, etc.)
§Examples
use countio::Counter;
use std::io::Cursor;
let data = vec![1, 2, 3, 4, 5];
let cursor = Cursor::new(data);
let counter = Counter::new(cursor);
assert_eq!(counter.reader_bytes(), 0);
assert_eq!(counter.writer_bytes(), 0);Sourcepub const fn with_bytes(
inner: D,
reader_bytes: usize,
writer_bytes: usize,
) -> Self
pub const fn with_bytes( inner: D, reader_bytes: usize, writer_bytes: usize, ) -> Self
Creates a new Counter<D> with pre-existing read/written byte counts.
This is useful when you want to continue counting from a previous session or when wrapping an I/O object that has already processed some data.
§Arguments
inner- The I/O object to wrapreader_bytes- Initial count of bytes readwriter_bytes- Initial count of bytes written
§Examples
use countio::Counter;
use std::io::Cursor;
let data = vec![1, 2, 3, 4, 5];
let cursor = Cursor::new(data);
let counter = Counter::with_bytes(cursor, 100, 50);
assert_eq!(counter.reader_bytes(), 100);
assert_eq!(counter.writer_bytes(), 50);Sourcepub const fn reader_bytes(&self) -> usize
pub const fn reader_bytes(&self) -> usize
Returns the total number of bytes read from the underlying I/O object.
This count includes all bytes successfully read through any of the
Read or BufRead trait methods.
§Examples
use std::io::Read;
use countio::Counter;
let data = b"Hello, World!";
let mut reader = Counter::new(&data[..]);
let mut buffer = [0u8; 5];
reader.read_exact(&mut buffer).unwrap();
assert_eq!(reader.reader_bytes(), 5);
assert_eq!(reader.writer_bytes(), 0);Sourcepub const fn writer_bytes(&self) -> usize
pub const fn writer_bytes(&self) -> usize
Returns the total number of bytes written to the underlying I/O object.
This count includes all bytes successfully written through any of the
Write trait methods.
§Examples
use std::io::Write;
use countio::Counter;
let mut writer = Counter::new(Vec::new());
writer.write_all(b"Hello").unwrap();
writer.write_all(b", World!").unwrap();
assert_eq!(writer.writer_bytes(), 13);
assert_eq!(writer.reader_bytes(), 0);Sourcepub const fn total_bytes(&self) -> u128
pub const fn total_bytes(&self) -> u128
Returns the total number of bytes processed (read + written) as a u128.
This is the sum of all bytes that have been read from or written to
the underlying I/O object since the Counter was created. Using u128
prevents overflow issues that could occur with large byte counts.
§Examples
use std::io::{Read, Write};
use countio::Counter;
let mut counter = Counter::new(Vec::new());
counter.write_all(b"Hello").unwrap();
let data = b"World";
let mut reader = Counter::new(&data[..]);
let mut buf = [0u8; 5];
reader.read(&mut buf).unwrap();
assert_eq!(counter.total_bytes(), 5);
assert_eq!(reader.total_bytes(), 5);Sourcepub fn into_inner(self) -> D
pub fn into_inner(self) -> D
Consumes the Counter<D> and returns the underlying I/O object.
This is useful when you need to recover the original I/O object,
perhaps to pass it to code that doesn’t know about the Counter wrapper.
§Examples
use std::io::Write;
use countio::Counter;
let original_writer = Vec::new();
let mut counter = Counter::new(original_writer);
counter.write_all(b"Hello").unwrap();
let recovered_writer = counter.into_inner();
assert_eq!(recovered_writer, b"Hello");Sourcepub const fn get_ref(&self) -> &D
pub const fn get_ref(&self) -> &D
Gets a reference to the underlying I/O object.
This allows you to access the wrapped object’s methods directly
without consuming the Counter.
§Examples
use countio::Counter;
use std::io::Cursor;
let data = vec![1, 2, 3, 4, 5];
let cursor = Cursor::new(data.clone());
let counter = Counter::new(cursor);
assert_eq!(counter.get_ref().position(), 0);Sourcepub const fn get_mut(&mut self) -> &mut D
pub const fn get_mut(&mut self) -> &mut D
Gets a mutable reference to the underlying I/O object.
This allows you to modify the wrapped object directly. Note that
any bytes read or written through the direct reference will not
be counted by the Counter.
§Examples
use countio::Counter;
use std::io::Cursor;
let data = vec![1, 2, 3, 4, 5];
let cursor = Cursor::new(data);
let mut counter = Counter::new(cursor);
counter.get_mut().set_position(2);
assert_eq!(counter.get_ref().position(), 2);Sourcepub const fn reset(&mut self)
pub const fn reset(&mut self)
Resets the byte counters to zero without affecting the underlying I/O object.
This is useful when you want to start counting from a fresh state without recreating the wrapper or losing the underlying object’s state.
§Examples
use std::io::{Read, Write};
use countio::Counter;
let mut counter = Counter::new(Vec::new());
counter.write_all(b"Hello").unwrap();
assert_eq!(counter.writer_bytes(), 5);
counter.reset();
assert_eq!(counter.writer_bytes(), 0);
assert_eq!(counter.reader_bytes(), 0);
// The underlying data is preserved
assert_eq!(counter.get_ref(), b"Hello");Trait Implementations§
Source§impl<R: AsyncBufRead + Unpin> AsyncBufRead for Counter<R>
Available on crate feature futures only.
impl<R: AsyncBufRead + Unpin> AsyncBufRead for Counter<R>
futures only.Source§impl<R: AsyncBufRead + Unpin> AsyncBufRead for Counter<R>
Available on crate feature tokio only.
impl<R: AsyncBufRead + Unpin> AsyncBufRead for Counter<R>
tokio only.Source§impl<R: AsyncRead + Unpin> AsyncRead for Counter<R>
Available on crate feature futures only.
impl<R: AsyncRead + Unpin> AsyncRead for Counter<R>
futures only.Source§impl<W: AsyncWrite + Unpin> AsyncWrite for Counter<W>
Available on crate feature futures only.
impl<W: AsyncWrite + Unpin> AsyncWrite for Counter<W>
futures only.Source§fn poll_write(
self: Pin<&mut Self>,
ctx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize>>
fn poll_write( self: Pin<&mut Self>, ctx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize>>
buf into the object. Read moreSource§fn poll_flush(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Result<()>>
fn poll_flush(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Result<()>>
Source§impl<W: AsyncWrite + Unpin> AsyncWrite for Counter<W>
Available on crate feature tokio only.
impl<W: AsyncWrite + Unpin> AsyncWrite for Counter<W>
tokio only.Source§fn poll_write(
self: Pin<&mut Self>,
ctx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize>>
fn poll_write( self: Pin<&mut Self>, ctx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize>>
buf into the object. Read moreSource§fn poll_flush(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Result<()>>
fn poll_flush(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Result<()>>
Source§fn poll_shutdown(
self: Pin<&mut Self>,
ctx: &mut Context<'_>,
) -> Poll<Result<()>>
fn poll_shutdown( self: Pin<&mut Self>, ctx: &mut Context<'_>, ) -> Poll<Result<()>>
Source§fn poll_write_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[IoSlice<'_>],
) -> Poll<Result<usize, Error>>
fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll<Result<usize, Error>>
poll_write, except that it writes from a slice of buffers. Read moreSource§fn is_write_vectored(&self) -> bool
fn is_write_vectored(&self) -> bool
poll_write_vectored
implementation. Read moreSource§impl<R: BufRead> BufRead for Counter<R>
Available on crate feature std only.
impl<R: BufRead> BufRead for Counter<R>
std only.Source§fn fill_buf(&mut self) -> Result<&[u8]>
fn fill_buf(&mut self) -> Result<&[u8]>
Read methods, if empty. Read moreSource§fn consume(&mut self, amt: usize)
fn consume(&mut self, amt: usize)
amount of additional bytes from the internal buffer as having been read.
Subsequent calls to read only return bytes that have not been marked as read. Read moreSource§fn has_data_left(&mut self) -> Result<bool, Error>
fn has_data_left(&mut self) -> Result<bool, Error>
buf_read_has_data_left)read. Read more1.83.0 · Source§fn skip_until(&mut self, byte: u8) -> Result<usize, Error>
fn skip_until(&mut self, byte: u8) -> Result<usize, Error>
byte or EOF is reached. Read more1.0.0 · Source§fn read_line(&mut self, buf: &mut String) -> Result<usize, Error>
fn read_line(&mut self, buf: &mut String) -> Result<usize, Error>
0xA byte) is reached, and append
them to the provided String buffer. Read moreSource§impl<R: Read> Read for Counter<R>
Available on crate feature std only.
impl<R: Read> Read for Counter<R>
std only.Source§fn read(&mut self, buf: &mut [u8]) -> Result<usize>
fn read(&mut self, buf: &mut [u8]) -> Result<usize>
1.36.0 · Source§fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>
read, except that it reads into a slice of buffers. Read moreSource§fn is_read_vectored(&self) -> bool
fn is_read_vectored(&self) -> bool
can_vector)1.0.0 · Source§fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>
buf. Read more1.0.0 · Source§fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>
fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>
buf. Read more1.6.0 · Source§fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>
buf. Read moreSource§fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>
fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>
read_buf)Source§fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>
fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>
read_buf)cursor. Read more1.0.0 · Source§fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
fn by_ref(&mut self) -> &mut Selfwhere
Self: Sized,
Read. Read more1.0.0 · Source§fn chain<R>(self, next: R) -> Chain<Self, R>
fn chain<R>(self, next: R) -> Chain<Self, R>
Source§impl<D: Seek> Seek for Counter<D>
Available on crate feature std only.
impl<D: Seek> Seek for Counter<D>
std only.Source§fn seek(&mut self, pos: SeekFrom) -> Result<u64>
fn seek(&mut self, pos: SeekFrom) -> Result<u64>
1.55.0 · Source§fn rewind(&mut self) -> Result<(), Error>
fn rewind(&mut self) -> Result<(), Error>
Source§fn stream_len(&mut self) -> Result<u64, Error>
fn stream_len(&mut self) -> Result<u64, Error>
seek_stream_len)Source§impl<W: Write> Write for Counter<W>
Available on crate feature std only.
impl<W: Write> Write for Counter<W>
std only.Source§fn write(&mut self, buf: &[u8]) -> Result<usize>
fn write(&mut self, buf: &[u8]) -> Result<usize>
Source§fn flush(&mut self) -> Result<()>
fn flush(&mut self) -> Result<()>
Source§fn is_write_vectored(&self) -> bool
fn is_write_vectored(&self) -> bool
can_vector)1.0.0 · Source§fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>
fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>
Source§fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>
write_all_vectored)