You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.2 KiB

use super::*;
use std::{
io::{self, Read, Write},
};
pub trait Tuple2Ext<T,U>: Sized
{
fn swap(self) -> (U, T);
}
impl<T, U> Tuple2Ext<T,U> for (T, U)
{
#[inline(always)] fn swap(self) -> (U, T) {
(self.1, self.0)
}
}
/// A counter for num of bytes read/written from a `Read`/`Write` stream.
#[derive(Debug)]
pub struct IOCounter<T: ?Sized>(usize, T);
impl<R: ?Sized + io::Read> io::Read for IOCounter<R>
{
#[inline] fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let w = self.1.read(buf)?;
self.0+=w;
Ok(w)
}
}
impl<W: ?Sized + io::Write> io::Write for IOCounter<W>
{
#[inline] fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let w= self.1.write(buf)?;
self.0+=w;
Ok(w)
}
#[inline(always)] fn flush(&mut self) -> io::Result<()> {
self.1.flush()
}
}
impl<T: ?Sized> IOCounter<T>
{
/// The current counted bytes i/o'd
#[inline] pub fn count(&self) -> usize
{
self.0
}
/// Reference to the inner stream
#[inline] pub fn inner(&self) -> &T
{
&self.1
}
/// Mutable reference to the inner stream
#[inline] pub fn inner_mut(&mut self) -> &mut T
{
&mut self.1
}
/// Mutable reference to the count.
/// Use this to set the count.
#[inline(always)] pub fn count_mut(&mut self) -> &mut usize
{
&mut self.0
}
/// Reset count to 0.
#[inline] pub fn reset(&mut self)
{
*self.count_mut() = 0;
}
}
impl<T> IOCounter<T>
{
/// Create a new i/o counting wrapper.
#[inline(always)] pub fn new(val: T) -> Self
{
Self(0, val)
}
/// Consume into inner stream
#[inline(always)] pub fn into_inner(self) -> T
{
self.1
}
}
pub trait IOCounterReadExt
{
/// Wrap an `IOCounter` over this `Read` stream.
fn with_counter(self) -> IOCounter<Self>;
}
pub trait IOCounterWriteExt
{
/// Wrap an `IOCounter` over this `Write` stream.
fn with_counter(self) -> IOCounter<Self>;
}
impl<W: io::Write> IOCounterWriteExt for W
{
#[inline] fn with_counter(self) -> IOCounter<Self> {
IOCounter::new(self)
}
}
impl<R: io::Read> IOCounterReadExt for R
{
#[inline] fn with_counter(self) -> IOCounter<Self> {
IOCounter::new(self)
}
}