async-stream-packed 0.2.2

Asynchronous stream packed.
Documentation
use std::io;

use futures_x_io::{AsyncRead, AsyncWrite};

use crate::upgradable::{Inner, UpgradableAsyncStream, Upgrader};

//
//
//
pub trait UpgraderExtRefer<S>: Upgrader<S> {
    fn get_ref(output: &Self::Output) -> &S;
    fn get_mut(output: &mut Self::Output) -> &mut S;
}

impl<S> UpgraderExtRefer<S> for ()
where
    S: AsyncRead + AsyncWrite + Unpin + Send + 'static,
{
    fn get_ref(output: &<Self as Upgrader<S>>::Output) -> &S {
        output
    }
    fn get_mut(output: &mut <Self as Upgrader<S>>::Output) -> &mut S {
        output
    }
}

impl<S, SU> UpgradableAsyncStream<S, SU>
where
    SU: UpgraderExtRefer<S>,
{
    pub fn get_ref(&self) -> &S {
        match &self.inner {
            Inner::Pending(s, _) => &s,
            Inner::Upgraded(s, _) => SU::get_ref(s),
            Inner::None => panic!("never"),
        }
    }

    pub fn get_mut(&mut self) -> &mut S {
        match &mut self.inner {
            Inner::Pending(s, _) => s,
            Inner::Upgraded(s, _) => SU::get_mut(s),
            Inner::None => panic!("never"),
        }
    }
}

//
//
//
pub trait UpgraderExtIntoStream<S>: Upgrader<S> {
    fn into_stream(output: Self::Output) -> io::Result<S>;
}

impl<S> UpgraderExtIntoStream<S> for ()
where
    S: AsyncRead + AsyncWrite + Unpin + Send + 'static,
{
    fn into_stream(output: <Self as Upgrader<S>>::Output) -> io::Result<S> {
        Ok(output)
    }
}

impl<S, SU> UpgradableAsyncStream<S, SU>
where
    SU: UpgraderExtIntoStream<S>,
{
    pub fn into_stream(self) -> io::Result<S> {
        match self.inner {
            Inner::Pending(s, _) => Ok(s),
            Inner::Upgraded(s, _) => SU::into_stream(s),
            Inner::None => panic!("never"),
        }
    }
}

//
//
//
impl<S, SU> UpgradableAsyncStream<S, SU>
where
    SU: Upgrader<S>,
{
    pub fn try_into_stream(self) -> io::Result<S> {
        match self.inner {
            Inner::Pending(s, _) => Ok(s),
            Inner::Upgraded(_, _) => Err(io::Error::new(io::ErrorKind::Other, "unimplemented")),
            Inner::None => panic!("never"),
        }
    }
}

impl<S, SU> UpgradableAsyncStream<S, SU>
where
    SU: Upgrader<S>,
{
    pub fn try_into_upgraded_stream(self) -> io::Result<SU::Output> {
        match self.inner {
            Inner::Pending(_, _) => Err(io::Error::new(io::ErrorKind::Other, "unimplemented")),
            Inner::Upgraded(s, _) => Ok(s),
            Inner::None => panic!("never"),
        }
    }
}