use bytes::Bytes;
use futures::{Sink, Stream};
use std::io;
use std::pin::Pin;
use std::task::{Context, Poll};
pub struct SocketStream<S> {
socket: S,
}
impl<S> SocketStream<S> {
pub const fn new(socket: S) -> Self {
Self { socket }
}
pub fn into_inner(self) -> S {
self.socket
}
pub const fn get_ref(&self) -> &S {
&self.socket
}
pub fn get_mut(&mut self) -> &mut S {
&mut self.socket
}
}
pub trait RecvSocket {
fn poll_recv(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<io::Result<Vec<Bytes>>>>;
}
impl<S> Stream for SocketStream<S>
where
S: RecvSocket + Unpin,
{
type Item = io::Result<Vec<Bytes>>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Pin::new(&mut self.socket).poll_recv(cx)
}
}
pub struct SocketSink<S> {
socket: S,
pending: Option<Vec<Bytes>>,
}
impl<S> SocketSink<S> {
pub const fn new(socket: S) -> Self {
Self {
socket,
pending: None,
}
}
pub fn into_inner(self) -> S {
self.socket
}
pub const fn get_ref(&self) -> &S {
&self.socket
}
pub fn get_mut(&mut self) -> &mut S {
&mut self.socket
}
}
pub trait SendSocket {
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>;
fn poll_send(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
msg: Vec<Bytes>,
) -> Poll<io::Result<()>>;
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>;
}
impl<S> Sink<Vec<Bytes>> for SocketSink<S>
where
S: SendSocket + Unpin,
{
type Error = io::Error;
fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Pin::new(&mut self.socket).poll_ready(cx)
}
fn start_send(mut self: Pin<&mut Self>, item: Vec<Bytes>) -> Result<(), Self::Error> {
self.pending = Some(item);
Ok(())
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
if let Some(msg) = self.pending.take() {
match Pin::new(&mut self.socket).poll_send(cx, msg.clone()) {
Poll::Ready(Ok(())) => {}
Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
Poll::Pending => {
self.pending = Some(msg);
return Poll::Pending;
}
}
}
Pin::new(&mut self.socket).poll_flush(cx)
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.poll_flush(cx)
}
}
pub struct SocketStreamSink<S> {
socket: S,
pending: Option<Vec<Bytes>>,
}
impl<S> SocketStreamSink<S> {
pub const fn new(socket: S) -> Self {
Self {
socket,
pending: None,
}
}
pub fn into_inner(self) -> S {
self.socket
}
pub const fn get_ref(&self) -> &S {
&self.socket
}
pub fn get_mut(&mut self) -> &mut S {
&mut self.socket
}
}
impl<S> Stream for SocketStreamSink<S>
where
S: RecvSocket + Unpin,
{
type Item = io::Result<Vec<Bytes>>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
Pin::new(&mut self.socket).poll_recv(cx)
}
}
impl<S> Sink<Vec<Bytes>> for SocketStreamSink<S>
where
S: SendSocket + Unpin,
{
type Error = io::Error;
fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Pin::new(&mut self.socket).poll_ready(cx)
}
fn start_send(mut self: Pin<&mut Self>, item: Vec<Bytes>) -> Result<(), Self::Error> {
self.pending = Some(item);
Ok(())
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
if let Some(msg) = self.pending.take() {
match Pin::new(&mut self.socket).poll_send(cx, msg.clone()) {
Poll::Ready(Ok(())) => {}
Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
Poll::Pending => {
self.pending = Some(msg);
return Poll::Pending;
}
}
}
Pin::new(&mut self.socket).poll_flush(cx)
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.poll_flush(cx)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_stream_creation() {
struct MockSocket;
let socket = MockSocket;
let stream = SocketStream::new(socket);
let _socket = stream.into_inner();
}
#[test]
fn test_sink_creation() {
struct MockSocket;
let socket = MockSocket;
let sink = SocketSink::new(socket);
let _socket = sink.into_inner();
}
#[test]
fn test_stream_sink_creation() {
struct MockSocket;
let socket = MockSocket;
let adapter = SocketStreamSink::new(socket);
let _socket = adapter.into_inner();
}
}