rust_engineio/asynchronous/
transport.rs

1use crate::error::Result;
2use adler32::adler32;
3use async_trait::async_trait;
4use bytes::Bytes;
5use futures_util::Stream;
6use std::{pin::Pin, time::SystemTime};
7use url::Url;
8
9use super::async_transports::{PollingTransport, WebsocketSecureTransport, WebsocketTransport};
10
11#[async_trait]
12pub trait AsyncTransport: Stream<Item = Result<Bytes>> + Unpin {
13    /// Sends a packet to the server. This optionally handles sending of a
14    /// socketio binary attachment via the boolean attribute `is_binary_att`.
15    async fn emit(&self, data: Bytes, is_binary_att: bool) -> Result<()>;
16
17    /// Returns start of the url. ex. http://localhost:2998/engine.io/?EIO=4&transport=polling
18    /// Must have EIO and transport already set.
19    async fn base_url(&self) -> Result<Url>;
20
21    /// Used to update the base path, like when adding the sid.
22    async fn set_base_url(&self, base_url: Url) -> Result<()>;
23
24    /// Full query address
25    async fn address(&self) -> Result<Url>
26    where
27        Self: Sized,
28    {
29        let reader = format!("{:#?}", SystemTime::now());
30        let hash = adler32(reader.as_bytes()).unwrap();
31        let mut url = self.base_url().await?;
32        url.query_pairs_mut().append_pair("t", &hash.to_string());
33        Ok(url)
34    }
35}
36
37#[derive(Debug, Clone)]
38pub enum AsyncTransportType {
39    Polling(PollingTransport),
40    Websocket(WebsocketTransport),
41    WebsocketSecure(WebsocketSecureTransport),
42}
43
44impl From<PollingTransport> for AsyncTransportType {
45    fn from(transport: PollingTransport) -> Self {
46        AsyncTransportType::Polling(transport)
47    }
48}
49
50impl From<WebsocketTransport> for AsyncTransportType {
51    fn from(transport: WebsocketTransport) -> Self {
52        AsyncTransportType::Websocket(transport)
53    }
54}
55
56impl From<WebsocketSecureTransport> for AsyncTransportType {
57    fn from(transport: WebsocketSecureTransport) -> Self {
58        AsyncTransportType::WebsocketSecure(transport)
59    }
60}
61
62#[cfg(feature = "async")]
63impl AsyncTransportType {
64    pub fn as_transport(&self) -> &(dyn AsyncTransport + Send) {
65        match self {
66            AsyncTransportType::Polling(transport) => transport,
67            AsyncTransportType::Websocket(transport) => transport,
68            AsyncTransportType::WebsocketSecure(transport) => transport,
69        }
70    }
71
72    pub fn as_pin_box(&mut self) -> Pin<Box<&mut (dyn AsyncTransport + Send)>> {
73        match self {
74            AsyncTransportType::Polling(transport) => Box::pin(transport),
75            AsyncTransportType::Websocket(transport) => Box::pin(transport),
76            AsyncTransportType::WebsocketSecure(transport) => Box::pin(transport),
77        }
78    }
79}