diff --git a/Cargo.toml b/Cargo.toml index 597aaf51..2ce2ed53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,3 @@ [workspace] members = ["engineio", "socketio"] +resolver = "2" diff --git a/engineio/src/asynchronous/client/async_client.rs b/engineio/src/asynchronous/client/async_client.rs index 99b0d0dd..783179eb 100644 --- a/engineio/src/asynchronous/client/async_client.rs +++ b/engineio/src/asynchronous/client/async_client.rs @@ -88,7 +88,7 @@ impl Debug for Client { } } -#[cfg(all(test))] +#[cfg(test)] mod test { use super::*; diff --git a/engineio/src/asynchronous/mod.rs b/engineio/src/asynchronous/mod.rs index 97bd9073..a27ae264 100644 --- a/engineio/src/asynchronous/mod.rs +++ b/engineio/src/asynchronous/mod.rs @@ -1,7 +1,7 @@ pub mod async_transports; pub mod transport; -pub(self) mod async_socket; +mod async_socket; #[cfg(feature = "async-callbacks")] mod callback; #[cfg(feature = "async")] diff --git a/engineio/src/client/client.rs b/engineio/src/client/client.rs index dc22ff77..69fdd8df 100644 --- a/engineio/src/client/client.rs +++ b/engineio/src/client/client.rs @@ -1,11 +1,10 @@ use super::super::socket::Socket as InnerSocket; use crate::callback::OptionalCallback; -use crate::socket::DEFAULT_MAX_POLL_TIMEOUT; -use crate::transport::Transport; - use crate::error::{Error, Result}; use crate::header::HeaderMap; use crate::packet::{HandshakePacket, Packet, PacketId}; +use crate::socket::DEFAULT_MAX_POLL_TIMEOUT; +use crate::transport::Transport; use crate::transports::{PollingTransport, WebsocketSecureTransport, WebsocketTransport}; use crate::ENGINE_IO_VERSION; use bytes::Bytes; diff --git a/engineio/src/client/mod.rs b/engineio/src/client/mod.rs index 2feb68ab..04bc91bc 100644 --- a/engineio/src/client/mod.rs +++ b/engineio/src/client/mod.rs @@ -1,3 +1,4 @@ +#![allow(clippy::module_inception)] mod client; pub use client::Iter; pub use {client::Client, client::ClientBuilder, client::Iter as SocketIter}; diff --git a/engineio/src/lib.rs b/engineio/src/lib.rs index 2ac5787d..2fcd16fb 100644 --- a/engineio/src/lib.rs +++ b/engineio/src/lib.rs @@ -85,7 +85,7 @@ pub mod client; /// Generic header map pub mod header; pub mod packet; -pub(self) mod socket; +mod socket; pub mod transport; pub mod transports; diff --git a/socketio/Cargo.toml b/socketio/Cargo.toml index 92598d71..7c1c18e3 100644 --- a/socketio/Cargo.toml +++ b/socketio/Cargo.toml @@ -48,3 +48,8 @@ async = ["async-callbacks", "rust_engineio/async", "tokio", "futures-util", "asy name = "async" path = "examples/async.rs" required-features = ["async"] + +[[example]] +name = "async-transmitter" +path = "examples/async_transmitter.rs" +required-features = ["async"] diff --git a/socketio/examples/async_transmitter.rs b/socketio/examples/async_transmitter.rs new file mode 100644 index 00000000..25d4ccfe --- /dev/null +++ b/socketio/examples/async_transmitter.rs @@ -0,0 +1,112 @@ +use futures_util::future::{BoxFuture, FutureExt}; +use rust_socketio::{ + asynchronous::{Client as SocketIOClient, ClientBuilder as SocketIOClientBuilder}, + Error as SocketIOError, Payload, +}; +use serde_json::{json, Value}; +use std::sync::{mpsc, Arc}; +use std::time::Duration; +use tokio::time::sleep; + +type JsonValues = Vec; + +fn test_event_handler<'event>(payload: Payload, socket: SocketIOClient) -> BoxFuture<'event, ()> { + async move { + if let Payload::Text(values) = payload { + match socket.try_transmitter::>() { + Ok(tx) => { + tx.send(values.to_owned()).map_or_else( + |err| eprintln!("{}", err), + |_| println!("Data transmitted successfully"), + ); + } + Err(err) => { + eprintln!("{}", err); + } + } + } + } + .boxed() +} + +fn error_event_handler<'event>(payload: Payload, _: SocketIOClient) -> BoxFuture<'event, ()> { + async move { eprintln!("Error: {:#?}", payload) }.boxed() +} + +struct ComplexData { + /// There should be many more fields below in real life, + /// probaly wrapped in Arc> if you're writing a more serious client. + data: String, +} + +struct TransmitterClient { + receiver: mpsc::Receiver, + complex: ComplexData, + client: SocketIOClient, +} + +impl TransmitterClient { + async fn connect(url: &str) -> Result { + let (sender, receiver) = mpsc::channel::(); + + let client = SocketIOClientBuilder::new(url) + .namespace("/admin") + .on("test", test_event_handler) + .on("error", error_event_handler) + .transmitter(Arc::new(sender)) + .connect() + .await?; + + Ok(Self { + client, + receiver, + complex: ComplexData { + data: String::from(""), + }, + }) + } + + async fn get_test(&mut self) -> Option { + match self.client.emit("test", json!({"got ack": true})).await { + Ok(_) => { + match self.receiver.recv() { + Ok(values) => { + // Json deserialization and parsing business logic should be implemented + // here to avoid over-complicating the handler callbacks. + if let Some(value) = values.first() { + if value.is_string() { + self.complex.data = String::from(value.as_str().unwrap()); + return Some(self.complex.data.clone()); + } + } + None + } + Err(err) => { + eprintln!("Transmission buffer is probably full: {}", err); + None + } + } + } + Err(err) => { + eprintln!("Server unreachable: {}", err); + None + } + } + } +} + +#[tokio::main] +async fn main() { + match TransmitterClient::connect("http://localhost:4200/").await { + Ok(mut client) => { + if let Some(test_data) = client.get_test().await { + println!("test event data from internal transmitter: {}", test_data); + } + } + Err(err) => { + eprintln!("Failed to connect to server: {}", err); + } + } + + sleep(Duration::from_secs(2)).await; +} diff --git a/socketio/examples/readme.rs b/socketio/examples/readme.rs index 00878192..c8610211 100644 --- a/socketio/examples/readme.rs +++ b/socketio/examples/readme.rs @@ -1,5 +1,6 @@ use rust_socketio::{ClientBuilder, Payload, RawClient}; use serde_json::json; +use std::thread::sleep; use std::time::Duration; fn main() { @@ -45,5 +46,7 @@ fn main() { .emit_with_ack("test", json_payload, Duration::from_secs(2), ack_callback) .expect("Server unreachable"); + sleep(Duration::from_secs(2)); + socket.disconnect().expect("Disconnect failed") } diff --git a/socketio/examples/sync_transmitter.rs b/socketio/examples/sync_transmitter.rs new file mode 100644 index 00000000..8e49ddea --- /dev/null +++ b/socketio/examples/sync_transmitter.rs @@ -0,0 +1,106 @@ +use rust_socketio::{ + client::Client as SocketIOClient, ClientBuilder as SocketIOClientBuilder, + Error as SocketIOError, Payload, RawClient, +}; +use serde_json::{json, Value}; +use std::sync::{mpsc, Arc}; +use std::thread::sleep; +use std::time::Duration; + +type JsonValues = Vec; + +fn test_event_handler(payload: Payload, socket: RawClient) { + if let Payload::Text(values) = payload { + match socket.try_transmitter::>() { + Ok(tx) => { + tx.send(values.to_owned()).map_or_else( + |err| eprintln!("{}", err), + |_| println!("Data transmitted successfully"), + ); + } + Err(err) => { + eprintln!("{}", err); + } + } + } +} + +fn error_event_handler(payload: Payload, _: RawClient) { + eprintln!("Error: {:#?}", payload); +} + +struct ComplexData { + /// There should be many more fields below in real life, + /// probaly wrapped in Arc> if you're writing a more serious client. + data: String, +} + +struct TransmitterClient { + client: SocketIOClient, + receiver: mpsc::Receiver, + complex: ComplexData, +} + +impl TransmitterClient { + fn connect(url: &str) -> Result { + let (sender, receiver) = mpsc::channel::(); + + let client = SocketIOClientBuilder::new(url) + .namespace("/admin") + .on("test", test_event_handler) + .on("error", error_event_handler) + .transmitter(Arc::new(sender)) + .connect()?; + + Ok(Self { + client, + receiver, + complex: ComplexData { + data: "".to_string(), + }, + }) + } + + fn get_test(&mut self) -> Option { + match self.client.emit("test", json!({"got ack": true})) { + Ok(_) => { + match self.receiver.recv() { + Ok(values) => { + // Json deserialization and parsing business logic should be implemented + // here to avoid over-complicating the handler callbacks. + if let Some(value) = values.first() { + if value.is_string() { + self.complex.data = String::from(value.as_str().unwrap()); + return Some(self.complex.data.clone()); + } + } + None + } + Err(err) => { + eprintln!("Transmission buffer is probably full: {}", err); + None + } + } + } + Err(err) => { + eprintln!("Server unreachable: {}", err); + None + } + } + } +} + +fn main() { + match TransmitterClient::connect("http://localhost:4200/") { + Ok(mut client) => { + if let Some(test_data) = client.get_test() { + println!("test event data from internal transmitter: {}", test_data); + } + } + Err(err) => { + eprintln!("Failed to connect to server: {}", err); + } + } + + sleep(Duration::from_secs(2)); +} diff --git a/socketio/src/asynchronous/client/client.rs b/socketio/src/asynchronous/client/async_client.rs similarity index 93% rename from socketio/src/asynchronous/client/client.rs rename to socketio/src/asynchronous/client/async_client.rs index 67feb7db..288d7b71 100644 --- a/socketio/src/asynchronous/client/client.rs +++ b/socketio/src/asynchronous/client/async_client.rs @@ -1,15 +1,3 @@ -use std::{ops::DerefMut, pin::Pin, sync::Arc}; - -use backoff::{backoff::Backoff, ExponentialBackoffBuilder}; -use futures_util::{future::BoxFuture, stream, Stream, StreamExt}; -use log::trace; -use rand::{thread_rng, Rng}; -use serde_json::Value; -use tokio::{ - sync::RwLock, - time::{sleep, Duration, Instant}, -}; - use super::{ ack::Ack, builder::ClientBuilder, @@ -21,6 +9,16 @@ use crate::{ packet::{Packet, PacketId}, Event, Payload, }; +use backoff::{backoff::Backoff, ExponentialBackoffBuilder}; +use futures_util::{future::BoxFuture, stream, Stream, StreamExt}; +use log::trace; +use rand::{thread_rng, Rng}; +use serde_json::Value; +use std::{ops::DerefMut, pin::Pin, sync::Arc}; +use tokio::{ + sync::RwLock, + time::{sleep, Duration, Instant}, +}; #[derive(Default)] enum DisconnectReason { @@ -68,10 +66,13 @@ pub struct Client { /// The inner socket client to delegate the methods to. socket: Arc>, outstanding_acks: Arc>>, - // namespace, for multiplexing messages + /// namespace, for multiplexing messages nsp: String, - // Data send in the opening packet (commonly used as for auth) + /// Data send in the opening packet (commonly used as for auth) auth: Option, + /// Ideally a Arc> to send data to a receiver that is outside + /// the 'static lifetime restrictions of the callback handlers. + transmitter: Arc, builder: Arc>, disconnect_reason: Arc>, } @@ -87,11 +88,63 @@ impl Client { nsp: builder.namespace.to_owned(), outstanding_acks: Arc::new(RwLock::new(Vec::new())), auth: builder.auth.clone(), + transmitter: builder.transmitter.clone().unwrap_or(Arc::new(())), builder: Arc::new(RwLock::new(builder)), disconnect_reason: Arc::new(RwLock::new(DisconnectReason::default())), }) } + /// Attempts to retrieve the transmitted data of type `D` from the transmitter. + /// + /// This function clones the transmitter and attempts to downcast it to an `Arc`. + /// If the downcast is successful, it returns the cloned data wrapped in a `Result`. + /// If the downcast fails, indicating that the transmitter contains data of an incompatible type, + /// it returns an `Err` with an `Error::TransmitterTypeResolutionFailure`. + /// + /// # Generic Parameters + /// + /// - `D`: The type of data expected to be transmitted. + /// + /// # Returns + /// + /// - `Result>`: A `Result` containing the cloned data if successful, or an error otherwise. + /// + /// # Example + /// + /// ```rust + /// use futures_util::future::{BoxFuture, FutureExt}; + /// use std::sync::{Arc, mpsc}; + /// use rust_socketio::{ + /// asynchronous::Client, + /// Payload, + /// }; + /// + /// fn event_handler<'event>(payload: Payload, socket: Client) -> BoxFuture<'event, ()> { + /// async move { + /// if let Payload::Text(values) = payload { + /// match socket.try_transmitter::>>() { + /// Ok(tx) => { + /// tx.send(values.to_owned()).map_or_else( + /// |err| eprintln!("{}", err), + /// |_| println!("Data transmitted successfully"), + /// ); + /// } + /// Err(err) => { + /// eprintln!("{}", err); + /// } + /// } + /// } + /// } + /// .boxed() + /// } + /// ``` + pub fn try_transmitter(&self) -> Result> { + match Arc::clone(&self.transmitter).downcast() { + Ok(data) => Ok(data), + Err(_) => Err(Error::TransmitterTypeResolutionFailure), + } + } + /// Connects the client to a server. Afterwards the `emit_*` methods can be /// called to interact with the server. pub(crate) async fn connect(&self) -> Result<()> { @@ -415,7 +468,7 @@ impl Client { .await; } if let Some(ref attachments) = socket_packet.attachments { - if let Some(payload) = attachments.get(0) { + if let Some(payload) = attachments.first() { ack.callback.deref_mut()( Payload::Binary(payload.to_owned()), self.clone(), @@ -445,7 +498,7 @@ impl Client { }; if let Some(attachments) = &packet.attachments { - if let Some(binary_payload) = attachments.get(0) { + if let Some(binary_payload) = attachments.first() { self.callback(&event, Payload::Binary(binary_payload.to_owned())) .await?; } @@ -585,7 +638,7 @@ mod test { use crate::{ asynchronous::{ - client::{builder::ClientBuilder, client::Client}, + client::{async_client::Client, builder::ClientBuilder}, ReconnectSettings, }, error::Result, diff --git a/socketio/src/asynchronous/client/builder.rs b/socketio/src/asynchronous/client/builder.rs index 44710e19..ed2d9e2a 100644 --- a/socketio/src/asynchronous/client/builder.rs +++ b/socketio/src/asynchronous/client/builder.rs @@ -1,3 +1,11 @@ +use super::{ + async_client::{Client, ReconnectSettings}, + callback::{ + Callback, DynAsyncAnyCallback, DynAsyncCallback, DynAsyncReconnectSettingsCallback, + }, +}; +use crate::asynchronous::socket::Socket as InnerSocket; +use crate::{error::Result, Event, Payload, TransportType}; use futures_util::future::BoxFuture; use log::trace; use native_tls::TlsConnector; @@ -6,18 +14,9 @@ use rust_engineio::{ header::{HeaderMap, HeaderValue}, }; use std::collections::HashMap; +use std::sync::Arc; use url::Url; -use crate::{error::Result, Event, Payload, TransportType}; - -use super::{ - callback::{ - Callback, DynAsyncAnyCallback, DynAsyncCallback, DynAsyncReconnectSettingsCallback, - }, - client::{Client, ReconnectSettings}, -}; -use crate::asynchronous::socket::Socket as InnerSocket; - /// A builder class for a `socket.io` socket. This handles setting up the client and /// configuring the callback, the namespace and metadata of the socket. If no /// namespace is specified, the default namespace `/` is taken. The `connect` method @@ -38,6 +37,7 @@ pub struct ClientBuilder { pub(crate) max_reconnect_attempts: Option, pub(crate) reconnect_delay_min: u64, pub(crate) reconnect_delay_max: u64, + pub(crate) transmitter: Option>, } impl ClientBuilder { @@ -97,9 +97,42 @@ impl ClientBuilder { max_reconnect_attempts: None, reconnect_delay_min: 1000, reconnect_delay_max: 5000, + transmitter: None, } } + /// Sets the data transmission object, ideally the standard libraries + /// multi-producer single consumer [`std::sync::mpsc::Sender`] should be used. + /// + /// # Example + /// + /// ```rust + /// use futures_util::FutureExt; + /// use std::sync::{Arc, mpsc}; + /// use rust_socketio::{ + /// asynchronous::{Client , ClientBuilder}, Error, + /// }; + /// + /// async fn connect(url: &str) -> Result { + /// let (sender, receiver) = mpsc::channel::>(); + /// + /// let client = ClientBuilder::new(url) + /// .namespace("/admin") + /// .on("error", |err, _| { + /// async move { eprintln!("Error: {:#?}", err) }.boxed() + /// }) + /// .transmitter(Arc::new(sender)) + /// .connect() + /// .await?; + /// + /// Ok(client) + /// } + /// ``` + pub fn transmitter(mut self, data: Arc) -> Self { + self.transmitter = Some(data); + self + } + /// Sets the target namespace of the client. The namespace should start /// with a leading `/`. Valid examples are e.g. `/admin`, `/foo`. /// If the String provided doesn't start with a leading `/`, it is diff --git a/socketio/src/asynchronous/client/callback.rs b/socketio/src/asynchronous/client/callback.rs index 3188b175..9e49ecc5 100644 --- a/socketio/src/asynchronous/client/callback.rs +++ b/socketio/src/asynchronous/client/callback.rs @@ -1,13 +1,11 @@ +use super::async_client::{Client, ReconnectSettings}; +use crate::{Event, Payload}; use futures_util::future::BoxFuture; use std::{ fmt::Debug, ops::{Deref, DerefMut}, }; -use crate::{Event, Payload}; - -use super::client::{Client, ReconnectSettings}; - /// Internal type, provides a way to store futures and return them in a boxed manner. pub(crate) type DynAsyncCallback = Box FnMut(Payload, Client) -> BoxFuture<'static, ()> + 'static + Send + Sync>; diff --git a/socketio/src/asynchronous/client/mod.rs b/socketio/src/asynchronous/client/mod.rs index bbf7cc92..bba5bd9c 100644 --- a/socketio/src/asynchronous/client/mod.rs +++ b/socketio/src/asynchronous/client/mod.rs @@ -1,5 +1,5 @@ mod ack; +pub(crate) mod async_client; pub(crate) mod builder; #[cfg(feature = "async-callbacks")] mod callback; -pub(crate) mod client; diff --git a/socketio/src/asynchronous/mod.rs b/socketio/src/asynchronous/mod.rs index e57cdf6a..8445c4cd 100644 --- a/socketio/src/asynchronous/mod.rs +++ b/socketio/src/asynchronous/mod.rs @@ -2,9 +2,9 @@ mod client; mod generator; mod socket; +pub use client::async_client::{Client, ReconnectSettings}; #[cfg(feature = "async")] pub use client::builder::ClientBuilder; -pub use client::client::{Client, ReconnectSettings}; // re-export the macro pub use crate::{async_any_callback, async_callback}; diff --git a/socketio/src/client/builder.rs b/socketio/src/client/builder.rs index 724971f0..35c0bd10 100644 --- a/socketio/src/client/builder.rs +++ b/socketio/src/client/builder.rs @@ -1,18 +1,16 @@ use super::super::{event::Event, payload::Payload}; use super::callback::Callback; -use super::client::Client; +use crate::client::callback::{SocketAnyCallback, SocketCallback}; +use crate::client::Client; +use crate::error::Result; +use crate::socket::Socket as InnerSocket; use crate::RawClient; use native_tls::TlsConnector; use rust_engineio::client::ClientBuilder as EngineIoClientBuilder; use rust_engineio::header::{HeaderMap, HeaderValue}; -use url::Url; - -use crate::client::callback::{SocketAnyCallback, SocketCallback}; -use crate::error::Result; use std::collections::HashMap; use std::sync::{Arc, Mutex}; - -use crate::socket::Socket as InnerSocket; +use url::Url; /// Flavor of Engine.IO transport. #[derive(Clone, Eq, PartialEq)] @@ -41,6 +39,7 @@ pub struct ClientBuilder { opening_headers: Option, transport_type: TransportType, auth: Option, + transmitter: Option>, pub(crate) reconnect: bool, pub(crate) reconnect_on_disconnect: bool, // None reconnect attempts represent infinity. @@ -92,6 +91,7 @@ impl ClientBuilder { opening_headers: None, transport_type: TransportType::Any, auth: None, + transmitter: None, reconnect: true, reconnect_on_disconnect: false, // None means infinity @@ -101,6 +101,35 @@ impl ClientBuilder { } } + /// Sets the data transmission object, ideally the standard libraries + /// multi-producer single consumer [`std::sync::mpsc::Sender`] should be used. + /// + /// ```rust + /// use rust_socketio::{ + /// client::Client, ClientBuilder, + /// Error , Payload, RawClient, + /// }; + /// use std::sync::{Arc, mpsc}; + /// + /// fn connect(url: &str) -> Result { + /// let (sender, receiver) = mpsc::channel::(); + /// + /// let client = ClientBuilder::new(url) + /// .namespace("/admin") + /// .on("error", |err, _| { + /// eprintln!("Error: {:#?}", err); + /// }) + /// .transmitter(Arc::new(sender)) + /// .connect()?; + /// + /// Ok(client) + /// } + /// ``` + pub fn transmitter(mut self, transmitter: Arc) -> Self { + self.transmitter = Some(transmitter); + self + } + /// Sets the target namespace of the client. The namespace should start /// with a leading `/`. Valid examples are e.g. `/admin`, `/foo`. pub fn namespace>(mut self, namespace: T) -> Self { @@ -365,6 +394,7 @@ impl ClientBuilder { self.on, self.on_any, self.auth, + self.transmitter.unwrap_or(Arc::new(())), )?; socket.connect()?; diff --git a/socketio/src/client/mod.rs b/socketio/src/client/mod.rs index e3884b64..924d45c7 100644 --- a/socketio/src/client/mod.rs +++ b/socketio/src/client/mod.rs @@ -1,3 +1,4 @@ +#![allow(clippy::module_inception)] mod builder; mod raw_client; diff --git a/socketio/src/client/raw_client.rs b/socketio/src/client/raw_client.rs index 0686683f..b06c84e7 100644 --- a/socketio/src/client/raw_client.rs +++ b/socketio/src/client/raw_client.rs @@ -41,6 +41,7 @@ pub struct RawClient { nsp: String, // Data send in the opening packet (commonly used as for auth) auth: Option, + transmitter: Arc, } impl RawClient { @@ -54,6 +55,7 @@ impl RawClient { on: Arc>>>, on_any: Arc>>>, auth: Option, + transmitter: Arc, ) -> Result { Ok(RawClient { socket, @@ -62,9 +64,49 @@ impl RawClient { on_any, outstanding_acks: Arc::new(Mutex::new(Vec::new())), auth, + transmitter, }) } + /// Attempts to retrieve the transmitted data of type `D` from the transmitter. + /// + /// This function clones the transmitter and attempts to downcast it to an `Arc`. + /// If the downcast is successful, it returns the cloned data wrapped in a `Result`. + /// If the downcast fails, indicating that the transmitter contains data of an incompatible type, + /// it returns an `Err` with an `Error::TransmitterTypeResolutionFailure`. + /// + /// # Example + /// + /// ```rust + /// use rust_socketio::{ + /// client::Client, ClientBuilder, + /// Error , Payload, RawClient, + /// }; + /// use std::sync::mpsc; + /// + /// fn event_handler(payload: Payload, socket: RawClient) { + /// if let Payload::Text(values) = payload { + /// match socket.try_transmitter::>>() { + /// Ok(tx) => { + /// tx.send(values.to_owned()).map_or_else( + /// |err| eprintln!("{}", err), + /// |_| println!("Data transmitted successfully"), + /// ); + /// } + /// Err(err) => { + /// eprintln!("{}", err); + /// } + /// } + /// } + /// } + /// ``` + pub fn try_transmitter(&self) -> Result> { + match Arc::clone(&self.transmitter).downcast() { + Ok(data) => Ok(data), + Err(_) => Err(Error::TransmitterTypeResolutionFailure), + } + } + /// Connects the client to a server. Afterwards the `emit_*` methods can be /// called to interact with the server. Attention: it's not allowed to add a /// callback after a call to this method. diff --git a/socketio/src/error.rs b/socketio/src/error.rs index cc25d897..2b0d2e6b 100644 --- a/socketio/src/error.rs +++ b/socketio/src/error.rs @@ -46,6 +46,8 @@ pub enum Error { InvalidAttachmentPacketType(u8), #[error("Underlying Engine.IO connection has closed")] StoppedEngineIoSocket, + #[error("Client::transmitter does not match the ClientBuilder::transmitter type")] + TransmitterTypeResolutionFailure, } pub(crate) type Result = std::result::Result; diff --git a/socketio/src/lib.rs b/socketio/src/lib.rs index b913eb4d..b0558e96 100644 --- a/socketio/src/lib.rs +++ b/socketio/src/lib.rs @@ -176,7 +176,7 @@ pub(crate) mod packet; /// Defines the types of payload (binary or string), that /// could be sent or received. pub mod payload; -pub(self) mod socket; +mod socket; /// Deprecated import since 0.3.0-alpha-2, use Error in the crate root instead. /// Contains the error type which will be returned with every result in this diff --git a/socketio/src/packet.rs b/socketio/src/packet.rs index e74dedb5..6b2629ed 100644 --- a/socketio/src/packet.rs +++ b/socketio/src/packet.rs @@ -2,7 +2,6 @@ use crate::error::{Error, Result}; use crate::{Event, Payload}; use bytes::Bytes; use serde::de::IgnoredAny; - use std::convert::TryFrom; use std::fmt::Write; use std::str::from_utf8 as str_from_utf8; @@ -34,10 +33,10 @@ impl Packet { /// Returns a packet for a payload, could be used for both binary and non binary /// events and acks. Convenience method. #[inline] - pub(crate) fn new_from_payload<'a>( + pub(crate) fn new_from_payload( payload: Payload, event: Event, - nsp: &'a str, + nsp: &str, id: Option, ) -> Result { match payload { @@ -216,7 +215,7 @@ impl TryFrom<&Bytes> for Packet { /// this member. This is done because the attachment is usually /// send in another packet. fn try_from(payload: &Bytes) -> Result { - let mut payload = str_from_utf8(&payload).map_err(Error::InvalidUtf8)?; + let mut payload = str_from_utf8(payload).map_err(Error::InvalidUtf8)?; let mut packet = Packet::default(); // packet_type