use super::*; use std::{ io::{self, Read, Write}, any::Any, marker::{Send, Sync}, fmt, }; pub trait Tuple2Ext: Sized { fn swap(self) -> (U, T); } impl Tuple2Ext 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(usize, T); impl io::Read for IOCounter { #[inline] fn read(&mut self, buf: &mut [u8]) -> io::Result { let w = self.1.read(buf)?; self.0+=w; Ok(w) } } impl io::Write for IOCounter { #[inline] fn write(&mut self, buf: &[u8]) -> io::Result { let w= self.1.write(buf)?; self.0+=w; Ok(w) } #[inline(always)] fn flush(&mut self) -> io::Result<()> { self.1.flush() } } impl IOCounter { /// 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 IOCounter { /// 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; } pub trait IOCounterWriteExt { /// Wrap an `IOCounter` over this `Write` stream. fn with_counter(self) -> IOCounter; } impl IOCounterWriteExt for W { #[inline] fn with_counter(self) -> IOCounter { IOCounter::new(self) } } impl IOCounterReadExt for R { #[inline] fn with_counter(self) -> IOCounter { IOCounter::new(self) } } /// A boxed `'static` value of anything anything that is `Send` and `Sync`. #[repr(transparent)] pub struct Anything(pub Box); impl fmt::Debug for Anything { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, ": (at: {:p}, sz: {})", Box::as_ref(&self.0), std::mem::size_of_val(Box::as_ref(&self.0))) } }