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

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)))
}
}