engineio-rs 0.1.5

An implementation of a engineio written in rust.
Documentation
use std::{borrow::Cow, fmt::Debug};

use async_trait::async_trait;
use bytes::Bytes;
use futures_util::Stream;
use tungstenite::Message;

use crate::transports::polling::ClientPollingTransport;
#[cfg(feature = "server")]
use crate::transports::polling::ServerPollingTransport;
use crate::{error::Result, transports::websocket::WebsocketTransport};

pub(crate) mod polling;
pub(crate) mod websocket;

#[async_trait]
pub trait Transport: Send + Debug + Unpin + Stream<Item = Result<Bytes>> {
    async fn emit(&self, payload: Data) -> Result<()>;
}

#[derive(Debug)]
pub enum Data {
    Text(Bytes),
    Binary(Bytes),
}

impl TryFrom<Data> for Message {
    type Error = crate::Error;

    fn try_from(payload: Data) -> std::result::Result<Self, Self::Error> {
        let message = match payload {
            Data::Text(data) => Message::text(Cow::Borrowed(std::str::from_utf8(data.as_ref())?)),
            Data::Binary(data) => Message::binary(Cow::Borrowed(data.as_ref())),
        };
        Ok(message)
    }
}

#[derive(Debug, Clone)]
pub enum TransportType {
    ClientPolling(ClientPollingTransport),
    #[cfg(feature = "server")]
    ServerPolling(ServerPollingTransport),
    Websocket(WebsocketTransport),
}

impl From<ClientPollingTransport> for TransportType {
    fn from(transport: ClientPollingTransport) -> Self {
        TransportType::ClientPolling(transport)
    }
}

#[cfg(feature = "server")]
impl From<ServerPollingTransport> for TransportType {
    fn from(transport: ServerPollingTransport) -> Self {
        TransportType::ServerPolling(transport)
    }
}

impl From<WebsocketTransport> for TransportType {
    fn from(transport: WebsocketTransport) -> Self {
        TransportType::Websocket(transport)
    }
}

impl TransportType {
    pub fn as_transport(&self) -> &(dyn Transport + Send) {
        match self {
            TransportType::ClientPolling(transport) => transport,
            #[cfg(feature = "server")]
            TransportType::ServerPolling(transport) => transport,
            TransportType::Websocket(transport) => transport,
        }
    }

    #[allow(clippy::redundant_allocation)]
    pub fn as_pin_box(&mut self) -> std::pin::Pin<Box<&mut (dyn Transport + Send)>> {
        match self {
            TransportType::ClientPolling(transport) => Box::pin(transport),
            #[cfg(feature = "server")]
            TransportType::ServerPolling(transport) => Box::pin(transport),
            TransportType::Websocket(transport) => Box::pin(transport),
        }
    }
}