async-stream-packed 0.1.2

Asynchronous stream packed.
Documentation
use std::io;
use std::mem;

use async_trait::async_trait;

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

pub type GradableAsyncStream<S, SU> = UpgradableAsyncStream<S, SU>;

#[async_trait]
pub trait Downgrader<S, SU>: Upgrader<S> {
    async fn downgrade(output: Self::Output, upgrader: Option<SU>) -> io::Result<(S, Option<SU>)>;
}

impl<S, SU> GradableAsyncStream<S, SU>
where
    SU: Upgrader<S> + Downgrader<S, SU>,
{
    pub async fn downgrade(&mut self) -> io::Result<()> {
        match mem::replace(&mut self.inner, Inner::None) {
            Inner::Pending((_, _)) => Err(io::Error::new(
                io::ErrorKind::Other,
                "do upgrade first or don't downgrade agent",
            )),
            Inner::Upgraded((stream, upgrader)) => {
                let (stream, upgrader) = SU::downgrade(stream, upgrader).await?;
                self.inner = Inner::Pending((stream, upgrader));
                Ok(())
            }
            Inner::None => panic!("never"),
        }
    }
}