use std::task::{ready, Context, Poll};
use bytes::{Buf, BufMut, Bytes, BytesMut};
use crate::{Error, Stats};
pub type BiStreams<S> = (<S as Session>::SendStream, <S as Session>::RecvStream);
pub trait Session {
type SendStream: SendStream;
type RecvStream: RecvStream;
type Error: Error;
fn poll_accept_uni(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Result<Self::RecvStream, Self::Error>>;
fn poll_accept_bi(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Result<BiStreams<Self>, Self::Error>>;
fn poll_open_uni(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Result<Self::SendStream, Self::Error>>;
fn poll_open_bi(&mut self, cx: &mut Context<'_>) -> Poll<Result<BiStreams<Self>, Self::Error>>;
fn poll_send_datagram(
&mut self,
cx: &mut Context<'_>,
payload: &[u8],
) -> Poll<Result<(), Self::Error>>;
fn poll_recv_datagram(&mut self, cx: &mut Context<'_>) -> Poll<Result<Bytes, Self::Error>>;
fn max_datagram_size(&self) -> usize;
fn protocol(&self) -> Option<&str>;
fn close(&mut self, code: u32, reason: &str);
fn poll_closed(&mut self, cx: &mut Context<'_>) -> Poll<Self::Error>;
fn stats(&self) -> impl Stats;
}
pub trait SendStream {
type Error: Error;
fn poll_write(&mut self, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize, Self::Error>>;
fn poll_write_buf<B: Buf>(
&mut self,
cx: &mut Context<'_>,
buf: &mut B,
) -> Poll<Result<usize, Self::Error>> {
let size = ready!(self.poll_write(cx, buf.chunk()))?;
buf.advance(size);
Poll::Ready(Ok(size))
}
fn set_priority(&mut self, order: u8);
fn finish(&mut self) -> Result<(), Self::Error>;
fn reset(&mut self, code: u32);
fn poll_closed(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
}
pub trait RecvStream {
type Error: Error;
fn poll_read(
&mut self,
cx: &mut Context<'_>,
dst: &mut [u8],
) -> Poll<Result<Option<usize>, Self::Error>>;
fn poll_read_buf<B: BufMut>(
&mut self,
cx: &mut Context<'_>,
buf: &mut B,
) -> Poll<Result<Option<usize>, Self::Error>> {
let len = buf.chunk_mut().len();
if len == 0 {
return Poll::Ready(Ok(Some(0)));
}
let dst = unsafe {
std::mem::transmute::<&mut bytes::buf::UninitSlice, &mut [u8]>(buf.chunk_mut())
};
let size = match ready!(self.poll_read(cx, dst))? {
Some(size) if size > 0 => size,
Some(_) => return Poll::Ready(Ok(Some(0))),
None => return Poll::Ready(Ok(None)),
};
unsafe { buf.advance_mut(size) };
Poll::Ready(Ok(Some(size)))
}
fn poll_read_chunk(
&mut self,
cx: &mut Context<'_>,
max: usize,
) -> Poll<Result<Option<Bytes>, Self::Error>> {
if max == 0 {
return Poll::Ready(Ok(Some(Bytes::new())));
}
let capacity = max.min(8 * 1024);
let mut buf = BytesMut::with_capacity(capacity);
let dst = unsafe {
std::mem::transmute::<&mut bytes::buf::UninitSlice, &mut [u8]>(buf.chunk_mut())
};
let dst = &mut dst[..capacity];
let size = match ready!(self.poll_read(cx, dst))? {
Some(size) if size > 0 => size,
Some(_) => return Poll::Ready(Ok(Some(Bytes::new()))),
None => return Poll::Ready(Ok(None)),
};
unsafe { buf.advance_mut(size) };
Poll::Ready(Ok(Some(buf.freeze())))
}
fn stop(&mut self, code: u32);
fn poll_closed(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
}