@ -18,6 +18,11 @@ pub mod prelude
pub use super ::StreamGateExt as _ ;
pub use super ::StreamLagExt as _ ;
pub use super ::INodeExt as _ ;
pub use super ::async_write_ext ::{
EitherWrite ,
DeadSink ,
} ;
}
pub trait INodeExt
@ -346,3 +351,147 @@ impl fmt::Display for SoftAssertionFailedError
}
} ;
}
mod async_write_ext {
use std ::ops ::{ Deref , DerefMut } ;
use tokio ::io ::{
self ,
AsyncWrite , AsyncRead ,
} ;
use std ::{
pin ::Pin ,
task ::{ Poll , Context } ,
} ;
use std ::marker ::PhantomData ;
#[ derive(Debug, Clone) ]
pub enum EitherWrite < ' a , T , U >
{
First ( T ) ,
Second ( U , PhantomData < & ' a mut U > ) ,
}
impl < ' a , T , U > Deref for EitherWrite < ' a , T , U >
where T : AsyncWrite + Unpin + ' a ,
U : AsyncWrite + Unpin + ' a
{
type Target = dyn AsyncWrite + Unpin + ' a ;
fn deref ( & self ) -> & Self ::Target {
match self {
Self ::First ( t ) = > t ,
Self ::Second ( u , _ ) = > u ,
}
}
}
impl < ' a , T , U > DerefMut for EitherWrite < ' a , T , U >
where T : AsyncWrite + Unpin + ' a ,
U : AsyncWrite + Unpin + ' a
{
fn deref_mut ( & mut self ) -> & mut Self ::Target {
match self {
Self ::First ( t ) = > t ,
Self ::Second ( u , _ ) = > u ,
}
}
}
impl < ' a , T , U > From < Result < T , U > > for EitherWrite < ' a , T , U >
where T : AsyncWrite + Unpin + ' a ,
U : AsyncWrite + Unpin + ' a
{
#[ inline ] fn from ( from : Result < T , U > ) -> Self
{
match from {
Ok ( v ) = > Self ::First ( v ) ,
Err ( v ) = > Self ::Second ( v , PhantomData ) ,
}
}
}
impl < ' a , T > EitherWrite < ' a , T , DeadSink >
{
#[ inline ] fn as_first_infallible ( & mut self ) -> & mut T
{
match self {
Self ::Second ( _ , _ ) = > unsafe { core ::hint ::unreachable_unchecked ( ) } ,
Self ::First ( t ) = > t
}
}
}
impl < ' a , U > EitherWrite < ' a , DeadSink , U >
{
#[ inline ] fn as_second_infallible ( & mut self ) -> & mut U
{
match self {
Self ::First ( _ ) = > unsafe { core ::hint ::unreachable_unchecked ( ) } ,
Self ::Second ( t , _ ) = > t
}
}
}
/* impl<'a, T> AsyncWrite for EitherWrite<'a, T, DeadSink>
where T : AsyncWrite + Unpin + ' a
{
#[ inline ] fn poll_write ( self : Pin < & mut Self > , cx : & mut Context < ' _ > , buf : & [ u8 ] ) -> Poll < Result < usize , io ::Error > > {
let this = unsafe { self . map_unchecked_mut ( | x | x . as_first_infallible ( ) ) } ;
this . poll_write ( cx , buf )
}
#[ inline ] fn poll_flush ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , io ::Error > > {
let this = unsafe { self . map_unchecked_mut ( | x | x . as_first_infallible ( ) ) } ;
this . poll_flush ( cx )
}
fn poll_shutdown ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , io ::Error > > {
let this = unsafe { self . map_unchecked_mut ( | x | x . as_first_infallible ( ) ) } ;
this . poll_shutdown ( cx )
}
} * /
impl < ' a , U > AsyncWrite for EitherWrite < ' a , DeadSink , U >
where U : AsyncWrite + Unpin + ' a
{
#[ inline ] fn poll_write ( self : Pin < & mut Self > , cx : & mut Context < ' _ > , buf : & [ u8 ] ) -> Poll < Result < usize , io ::Error > > {
let this = unsafe { self . map_unchecked_mut ( | x | x . as_second_infallible ( ) ) } ;
this . poll_write ( cx , buf )
}
#[ inline ] fn poll_flush ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , io ::Error > > {
let this = unsafe { self . map_unchecked_mut ( | x | x . as_second_infallible ( ) ) } ;
this . poll_flush ( cx )
}
fn poll_shutdown ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , io ::Error > > {
let this = unsafe { self . map_unchecked_mut ( | x | x . as_second_infallible ( ) ) } ;
this . poll_shutdown ( cx )
}
}
/// An `Infallible` type for `AsyncWrite` & `AsyncRead`
#[ derive(Debug) ]
pub enum DeadSink { }
impl AsyncWrite for DeadSink
{
#[ inline ] fn poll_flush ( self : Pin < & mut Self > , _cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , io ::Error > > {
unreachable! ( ) ;
}
#[ inline ] fn poll_write ( self : Pin < & mut Self > , _cx : & mut Context < ' _ > , _buf : & [ u8 ] ) -> Poll < Result < usize , io ::Error > > {
unreachable! ( ) ;
}
#[ inline ] fn poll_shutdown ( self : Pin < & mut Self > , _cx : & mut Context < ' _ > ) -> Poll < Result < ( ) , io ::Error > > {
unreachable! ( ) ;
}
}
impl AsyncRead for DeadSink
{
#[ inline ] fn poll_read ( self : Pin < & mut Self > , _cx : & mut Context < ' _ > , _buf : & mut [ u8 ] ) -> Poll < io ::Result < usize > > {
unreachable! ( ) ;
}
}
}