#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
mod stdlib;
#[cfg(feature = "futures")]
#[cfg_attr(docsrs, doc(cfg(feature = "futures")))]
mod futures;
#[cfg(feature = "tokio")]
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
mod tokio;
pub struct Counter<D> {
pub(crate) inner: D,
pub(crate) reader_bytes: usize,
pub(crate) writer_bytes: usize,
}
impl<D> Counter<D> {
#[inline]
pub const fn new(inner: D) -> Self {
Self::with_bytes(inner, 0, 0)
}
#[inline]
pub const fn with_bytes(inner: D, reader_bytes: usize, writer_bytes: usize) -> Self {
Self {
inner,
reader_bytes,
writer_bytes,
}
}
#[inline]
pub const fn reader_bytes(&self) -> usize {
self.reader_bytes
}
#[inline]
pub const fn writer_bytes(&self) -> usize {
self.writer_bytes
}
#[inline]
pub const fn total_bytes(&self) -> u128 {
(self.reader_bytes as u128) + (self.writer_bytes as u128)
}
#[inline]
pub fn into_inner(self) -> D {
self.inner
}
#[inline]
pub const fn get_ref(&self) -> &D {
&self.inner
}
#[inline]
pub const fn get_mut(&mut self) -> &mut D {
&mut self.inner
}
#[inline]
pub const fn reset(&mut self) {
self.reader_bytes = 0;
self.writer_bytes = 0;
}
}
impl<D> From<D> for Counter<D> {
#[inline]
fn from(inner: D) -> Self {
Self::new(inner)
}
}
impl<D: Clone> Clone for Counter<D> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
reader_bytes: self.reader_bytes,
writer_bytes: self.writer_bytes,
}
}
}
impl<D: Default> Default for Counter<D> {
fn default() -> Self {
Self::new(D::default())
}
}
impl<D: core::fmt::Debug> core::fmt::Debug for Counter<D> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Counter")
.field("inner", &self.inner)
.field("read", &self.reader_bytes)
.field("written", &self.writer_bytes)
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_inner() {
let writer = vec![8u8];
assert_eq!(writer.len(), 1);
let mut writer = Counter::new(writer);
writer.get_mut().clear();
assert_eq!(writer.get_ref().len(), 0);
let writer = writer.into_inner();
assert_eq!(writer.len(), 0);
}
#[test]
fn test_from() {
let _: Counter<_> = Vec::<u8>::new().into();
}
#[test]
fn test_with_bytes_creates_counter_with_initial_counts() {
let counter = Counter::with_bytes(Vec::<u8>::new(), 100, 200);
assert_eq!(counter.reader_bytes(), 100);
assert_eq!(counter.writer_bytes(), 200);
assert_eq!(counter.total_bytes(), 300);
}
#[test]
fn test_reset() {
use std::io::Write;
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);
assert_eq!(counter.total_bytes(), 0);
assert_eq!(counter.get_ref(), b"Hello");
}
#[test]
fn test_clone() {
use std::io::Write;
let mut counter = Counter::new(Vec::new());
counter.write_all(b"Hello").unwrap();
let cloned = counter.clone();
assert_eq!(cloned.writer_bytes(), 5);
assert_eq!(cloned.get_ref(), b"Hello");
}
#[test]
fn test_default() {
let counter: Counter<Vec<u8>> = Counter::default();
assert_eq!(counter.reader_bytes(), 0);
assert_eq!(counter.writer_bytes(), 0);
assert!(counter.get_ref().is_empty());
}
}