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.
128 lines
2.6 KiB
128 lines
2.6 KiB
use super::*;
|
|
use std::{
|
|
io::{self, Read, Write},
|
|
any::Any,
|
|
marker::{Send, Sync},
|
|
fmt,
|
|
};
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
/// A boxed `'static` value of anything anything that is `Send` and `Sync`.
|
|
#[repr(transparent)]
|
|
pub struct Anything(pub Box<dyn Any + Send + Sync + 'static>);
|
|
|
|
impl fmt::Debug for Anything
|
|
{
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
|
{
|
|
write!(f, "<opaque object>: (at: {:p}, sz: {})",
|
|
Box::as_ref(&self.0),
|
|
std::mem::size_of_val(Box::as_ref(&self.0)))
|
|
}
|
|
}
|