jetstream_websocket 9.5.0

Jetstream is a RPC framework for Rust, based on the 9P protocol and QUIC.
Documentation
#![doc(
    html_logo_url = "https://raw.githubusercontent.com/sevki/jetstream/main/logo/JetStream.png"
)]
#![doc(
    html_favicon_url = "https://raw.githubusercontent.com/sevki/jetstream/main/logo/JetStream.png"
)]
#![cfg_attr(docsrs, feature(doc_cfg))]

pub extern crate tokio_tungstenite;
use futures::{
    stream::{SplitSink, SplitStream},
    Sink, SinkExt, Stream, StreamExt,
};
use jetstream_rpc::{Frame, Protocol};
use jetstream_wireformat::wire_format_extensions::ConvertWireFormat;
use std::{
    io,
    marker::PhantomData,
    pin::Pin,
    task::{Context, Poll},
};
use tokio::net::TcpStream;
use tokio_tungstenite::WebSocketStream;
use tokio_tungstenite::{tungstenite::Message, MaybeTlsStream};

pub struct WebSocketTransport<P: Protocol>(
    SplitSink<WebSocketStream<MaybeTlsStream<TcpStream>>, Message>,
    SplitStream<WebSocketStream<MaybeTlsStream<TcpStream>>>,
    PhantomData<P>,
);

impl<P: Protocol + Unpin> From<WebSocketStream<MaybeTlsStream<TcpStream>>>
    for WebSocketTransport<P>
{
    fn from(ws: WebSocketStream<MaybeTlsStream<TcpStream>>) -> Self {
        let (read, write) = ws.split();
        WebSocketTransport(read, write, PhantomData)
    }
}
impl<P: Protocol + Unpin> Sink<jetstream_rpc::Frame<P::Request>>
    for WebSocketTransport<P>
{
    type Error = std::io::Error;

    fn poll_ready(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Result<(), Self::Error>> {
        self.get_mut()
            .0
            .poll_ready_unpin(cx)
            .map_err(io::Error::other)
    }

    fn start_send(
        self: Pin<&mut Self>,
        item: jetstream_rpc::Frame<P::Request>,
    ) -> Result<(), Self::Error> {
        self.get_mut()
            .0
            .start_send_unpin(Message::Binary(item.to_bytes()))
            .map_err(io::Error::other)
    }

    fn poll_flush(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Result<(), Self::Error>> {
        self.get_mut()
            .0
            .poll_flush_unpin(cx)
            .map_err(io::Error::other)
    }

    fn poll_close(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Result<(), Self::Error>> {
        self.get_mut()
            .0
            .poll_close_unpin(cx)
            .map_err(io::Error::other)
    }
}

impl<P: Protocol> Stream for WebSocketTransport<P>
where
    Self: Unpin,
{
    type Item = Result<jetstream_rpc::Frame<P::Response>, io::Error>;

    fn poll_next(
        self: Pin<&mut Self>,
        cx: &mut Context<'_>,
    ) -> Poll<Option<Self::Item>> {
        self.get_mut().1.poll_next_unpin(cx).map(|opt| {
            opt.map(|res| match res {
                Ok(msg) => {
                    let data = msg.into_data();
                    Frame::<P::Response>::from_bytes(&data)
                }
                Err(e) => Err(io::Error::other(e)),
            })
        })
    }
}