Skip to content

Commit

Permalink
doc(socketio): fix parser json specific doc
Browse files Browse the repository at this point in the history
  • Loading branch information
Totodore committed Oct 16, 2024
1 parent 0188b49 commit a94a32f
Show file tree
Hide file tree
Showing 13 changed files with 40 additions and 46 deletions.
2 changes: 1 addition & 1 deletion crates/parser-common/src/value/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ impl<'a, 'de, V: de::Visitor<'de>> Visitor<'de> for BinaryVisitor<'a, V> {
("_placeholder", Val::Placeholder(true), "num", Val::Num(idx))
| ("num", Val::Num(idx), "_placeholder", Val::Placeholder(true)) => {
// Serde is going through the data in a DFS manner, in the same way that socket.io JS parser encode placeholders.
// So we can safely pop the first element of the queue.
// So we can safely pop the first element of the queue. This is more efficient than shifting the queue.
let payload = self
.binary_payloads
.pop_front()
Expand Down
5 changes: 4 additions & 1 deletion crates/parser-common/src/value/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ struct Serializer<'a, S> {
ser: S,
/// This field requires UnsafeCell because we need to mutate the vector of binary payloads.
/// However we can't move &mut around because we need to pass by value every [`Serializer`] when we
/// instantiate them for new [`Compound`] types.
/// instantiate them for new [`Compound`] types. This remains safe because we only mutate the vector when
/// inserting new binary payloads and we never access it in other ways.
binary_payloads: &'a UnsafeCell<VecDeque<Bytes>>,
is_root: bool,
}
Expand Down Expand Up @@ -319,6 +320,8 @@ impl<'a, S: ser::Serializer> serde::Serializer for Serializer<'a, S> {
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
use serde::ser::SerializeMap;
let num = {
// SAFETY: the binary_payloads are only accessed in the context of the current serialization
// in a sequential manner. The only mutation place is here, hence it remains safe.
let bins = unsafe { self.binary_payloads.get().as_mut().unwrap() };
bins.push_back(Bytes::copy_from_slice(v));
bins.len() - 1
Expand Down
2 changes: 1 addition & 1 deletion crates/parser-msgpack/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub fn deserialize_packet(buff: Bytes) -> Result<Packet, ParseError<DecodeError>

// Current js socket.io msgpack implementation has a weird way to represent "undefined" with zeroed 1-ext.
// This is a little workaround to convert this to a proper "undefined" value.
if data == Bytes::from_static(&[0xd4, 0x00, 0x00]) {
if data.as_ref() == &[0xd4, 0x00, 0x00] {
data = Bytes::from_static(&[0xc0]); // nil
};

Expand Down
4 changes: 1 addition & 3 deletions crates/socketioxide/src/ack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,9 @@ pin_project_lite::pin_project! {
/// * As a [`Future`]: It will yield the first ack response received from the client.
/// Useful when expecting only one acknowledgement.
///
/// If the packet encoding failed an [`serde_json::Error`] is **immediately** returned.
///
/// If the client didn't respond before the timeout, the [`AckStream`] will yield
/// an [`AckError::Timeout`]. If the data sent by the client is not deserializable as `T`,
/// an [`AckError::Serde`] will be yielded.
/// an [`AckError::Decode`] will be yielded.
///
/// An [`AckStream`] can be created from:
/// * The [`SocketRef::emit_with_ack`] method, in this case there will be only one ack response.
Expand Down
4 changes: 2 additions & 2 deletions crates/socketioxide/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub enum BroadcastError {
#[error("Error sending data through the engine.io socket: {0:?}")]
Socket(Vec<SocketError>),

/// An error occurred while serializing the JSON packet.
/// An error occurred while serializing the packet.
#[error("Error serializing packet: {0:?}")]
Serialize(#[from] EncodeError),

Expand All @@ -65,7 +65,7 @@ pub enum BroadcastError {
/// Error type for sending operations.
#[derive(thiserror::Error, Debug)]
pub enum SendError {
/// An error occurred while serializing the JSON packet.
/// An error occurred while serializing the packet.
#[error("Error serializing packet: {0:?}")]
Serialize(#[from] EncodeError),

Expand Down
17 changes: 8 additions & 9 deletions crates/socketioxide/src/extract/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
//! ### Extractors for [`ConnectHandler`], [`ConnectMiddleware`], [`MessageHandler`] and [`DisconnectHandler`](crate::handler::DisconnectHandler).
//!
//! They can be used to extract data from the context of the handler and get specific params. Here are some examples of extractors:
//! * [`Data`]: extracts and deserialize to json any data, if a deserialization error occurs the handler won't be called:
//! - for [`ConnectHandler`]: extracts and deserialize to json the auth data
//! - for [`ConnectMiddleware`]: extract and deserialize to json the auth data.
//! In case of error, the middleware chain stops and a `connect_error` event is sent.
//! - for [`MessageHandler`]: extracts and deserialize to json the message data
//! * [`TryData`]: extracts and deserialize to json any data but with a `Result` type in case of error:
//! - for [`ConnectHandler`] and [`ConnectMiddleware`]:
//! extracts and deserialize to json the auth data
//! - for [`MessageHandler`]: extracts and deserialize to json the message data
//! * [`Data`]: extracts and deserialize from any receieved data, if a deserialization error occurs the handler won't be called:
//! - for [`ConnectHandler`]: extracts and deserialize from the incoming auth data
//! - for [`ConnectMiddleware`]: extract and deserialize from the incoming auth data.
//! In case of error, the middleware chain stops and a `connect_error` event is sent.
//! - for [`MessageHandler`]: extracts and deserialize from the incoming message data
//! * [`TryData`]: extracts and deserialize from the any received data but with a `Result` type in case of error:
//! - for [`ConnectHandler`] and [`ConnectMiddleware`]: extracts and deserialize from the incoming auth data
//! - for [`MessageHandler`]: extracts and deserialize from the incoming message data
//! * [`SocketRef`]: extracts a reference to the [`Socket`](crate::socket::Socket)
//! * [`SocketIo`](crate::SocketIo): extracts a reference to the whole socket.io server context.
//! * [`AckSender`]: Can be used to send an ack response to the current message event
Expand Down
3 changes: 0 additions & 3 deletions crates/socketioxide/src/handler/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
//! ## Example with sync closures
//! ```rust
//! # use socketioxide::SocketIo;
//! # use serde_json::Error;
//! # use socketioxide::extract::*;
//! let (svc, io) = SocketIo::new_svc();
//! // Here the handler is sync,
Expand All @@ -39,7 +38,6 @@
//! ## Example with async closures
//! ```rust
//! # use socketioxide::SocketIo;
//! # use serde_json::Error;
//! # use socketioxide::extract::*;
//! let (svc, io) = SocketIo::new_svc();
//! // Here the handler is async and extract the current socket and the auth payload
Expand All @@ -56,7 +54,6 @@
//! ## Example with async non anonymous functions
//! ```rust
//! # use socketioxide::SocketIo;
//! # use serde_json::Error;
//! # use socketioxide::extract::*;
//! async fn handler(s: SocketRef, TryData(auth): TryData<String>) {
//! tokio::time::sleep(std::time::Duration::from_secs(1)).await;
Expand Down
3 changes: 0 additions & 3 deletions crates/socketioxide/src/handler/disconnect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
//! ## Example with sync closures
//! ```rust
//! # use socketioxide::SocketIo;
//! # use serde_json::Error;
//! # use socketioxide::extract::*;
//! # use socketioxide::socket::DisconnectReason;
//! let (svc, io) = SocketIo::new_svc();
Expand All @@ -23,7 +22,6 @@
//! ## Example with async closures
//! ```rust
//! # use socketioxide::SocketIo;
//! # use serde_json::Error;
//! # use socketioxide::extract::*;
//! let (svc, io) = SocketIo::new_svc();
//! io.ns("/", |s: SocketRef| {
Expand All @@ -36,7 +34,6 @@
//! ## Example with async non anonymous functions
//! ```rust
//! # use socketioxide::SocketIo;
//! # use serde_json::Error;
//! # use socketioxide::extract::*;
//! # use socketioxide::socket::DisconnectReason;
//! async fn handler(s: SocketRef, reason: DisconnectReason) {
Expand Down
3 changes: 0 additions & 3 deletions crates/socketioxide/src/handler/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
//! ## Example with sync closures
//! ```rust
//! # use socketioxide::SocketIo;
//! # use serde_json::Error;
//! # use socketioxide::extract::*;
//! let (svc, io) = SocketIo::new_svc();
//! io.ns("/", |s: SocketRef| {
Expand All @@ -39,7 +38,6 @@
//! ## Example with async closures
//! ```rust
//! # use socketioxide::SocketIo;
//! # use serde_json::Error;
//! # use socketioxide::extract::*;
//! let (svc, io) = SocketIo::new_svc();
//! io.ns("/", |s: SocketRef| {
Expand All @@ -57,7 +55,6 @@
//! ## Example with async non anonymous handler
//! ```rust
//! # use socketioxide::SocketIo;
//! # use serde_json::Error;
//! # use socketioxide::extract::*;
//! // async named event handler
//! async fn on_event(s: SocketRef, Data(data): Data<serde_json::Value>, ack: AckSender) {
Expand Down
4 changes: 2 additions & 2 deletions crates/socketioxide/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,12 +706,12 @@ impl<A: Adapter> SocketIo<A> {
///
/// If the client didn't respond before the timeout, the [`AckStream`] will yield
/// an [`AckError::Timeout`]. If the data sent by the client is not deserializable as `V`,
/// an [`AckError::Serde`] will be yielded.
/// an [`AckError::Decode`] will be yielded.
///
/// [`timeout()`]: #method.timeout
/// [`Stream`]: futures_core::stream::Stream
/// [`Future`]: futures_core::future::Future
/// [`AckError::Serde`]: crate::AckError::Serde
/// [`AckError::Decode`]: crate::AckError::Decode
/// [`AckError::Timeout`]: crate::AckError::Timeout
/// [`AckError::Socket`]: crate::AckError::Socket
/// [`AckError::Socket(SocketError::Closed)`]: crate::SocketError::Closed
Expand Down
27 changes: 15 additions & 12 deletions crates/socketioxide/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,15 @@
//! the [`FromMessageParts`](handler::FromMessageParts) for the [`MessageHandler`](handler::MessageHandler) and the
//! [`FromDisconnectParts`](handler::FromDisconnectParts) for the [`DisconnectHandler`](handler::DisconnectHandler).
//!
//! Here are some examples of extractors:
//! * [`Data`](extract::Data): extracts and deserialize to json any data, if a deserialize error occurs the handler won't be called
//! - for [`ConnectHandler`](handler::ConnectHandler): extracts and deserialize to json the auth data
//! - for [`MessageHandler`](handler::MessageHandler): extracts and deserialize to json the message data
//! * [`TryData`](extract::TryData): extracts and deserialize to json any data but with a `Result` type in case of error
//! - for [`ConnectHandler`](handler::ConnectHandler): extracts and deserialize to json the auth data
//! - for [`MessageHandler`](handler::MessageHandler): extracts and deserialize to json the message data
//! They can be used to extract data from the context of the handler and get specific params. Here are some examples of extractors:
//! * [`Data`]: extracts and deserialize from any receieved data, if a deserialization error occurs the handler won't be called:
//! - for [`ConnectHandler`]: extracts and deserialize from the incoming auth data
//! - for [`ConnectMiddleware`]: extract and deserialize from the incoming auth data.
//! In case of error, the middleware chain stops and a `connect_error` event is sent.
//! - for [`MessageHandler`]: extracts and deserialize from the incoming message data
//! * [`TryData`]: extracts and deserialize from the any received data but with a `Result` type in case of error:
//! - for [`ConnectHandler`] and [`ConnectMiddleware`]: extracts and deserialize from the incoming auth data
//! - for [`MessageHandler`]: extracts and deserialize from the incoming message data
//! * [`SocketRef`](extract::SocketRef): extracts a reference to the [`Socket`](socket::Socket)
//! * [`AckSender`](extract::AckSender): Can be used to send an ack response to the current message event
//! * [`ProtocolVersion`]: extracts the protocol version of the socket
Expand Down Expand Up @@ -202,19 +204,20 @@
//!
//! ## [Emiting data](#emiting-data)
//! Data can be emitted to a socket with the [`Socket::emit`](socket::Socket) method. It takes an event name and a data argument.
//! The data argument is can be any type that implements the [`serde::Serialize`] trait.
//! The data argument can be any type that implements the [`serde::Serialize`] trait.
//!
//! You can emit from the [`SocketIo`] handle or the [`SocketRef`](extract::SocketRef).
//! The difference is that you can move the [`io`](SocketIo) handle everywhere because it is a cheaply cloneable struct.
//! The [`SocketRef`](extract::SocketRef) is a reference to the socket and cannot be cloned.
//! The [`SocketRef`](extract::SocketRef) is a reference to the socket and you should avoid storing it in your own code (e.g. in HashMap/Vec).
//! If you do so, you will have to remove the socket reference when the socket is disconnected to avoid memory leaks.
//!
//! Moreover the [`io`](SocketIo) handle can emit to any namespace while the [`SocketRef`](extract::SocketRef) can only emit to the namespace of the socket.
//!
//! When using any `emit` fn, if you provide tuple-like data (tuple, arrays), it will be considered as multiple arguments.
//! When using any `emit` fn, if you provide tuple-like data (tuple, arrays), it will be considered as multiple emit arguments.
//! If you send a vector it will be considered as a single argument.
//!
//! #### Emit errors
//! If the data can't be serialized to json, an [`EncodeError`] will be returned.
//! If the data can't be serialized, an [`EncodeError`] will be returned.
//!
//! If the socket is disconnected or the internal channel is full, a [`SendError`] will be returned.
//! Moreover, a tracing log will be emitted if the `tracing` feature is enabled.
Expand All @@ -241,7 +244,7 @@
//! If you want to emit/broadcast a message and await for a/many client(s) acknowledgment(s) you can use:
//! * [`SocketRef::emit_with_ack`] for a single client
//! * [`BroadcastOperators::emit_with_ack`] for broadcasting or [emit configuration](#emiting-data).
//! * [`SocketIo::emit_with_ack`] for broadcasting.
//! * [`SocketIo::emit_with_ack`] for broadcasting to an entire namespace.
//!
//! [`SocketRef::emit_with_ack`]: crate::extract::SocketRef#method.emit_with_ack
//! [`BroadcastOperators::emit_with_ack`]: crate::operators::BroadcastOperators#method.emit_with_ack
Expand Down
8 changes: 4 additions & 4 deletions crates/socketioxide/src/operators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,14 +367,14 @@ impl<A: Adapter> ConfOperators<'_, A> {
///
/// If the client didn't respond before the timeout, the [`AckStream`] will yield
/// an [`AckError::Timeout`]. If the data sent by the client is not deserializable as `V`,
/// an [`AckError::Serde`] will be yielded.
/// an [`AckError::Decode`] will be yielded.
///
/// [`timeout()`]: crate::operators::ConfOperators#method.timeout
/// [`SocketIoBuilder::ack_timeout`]: crate::SocketIoBuilder#method.ack_timeout
/// [`Stream`]: futures_core::stream::Stream
/// [`Future`]: futures_core::future::Future
/// [`AckError`]: crate::AckError
/// [`AckError::Serde`]: crate::AckError::Serde
/// [`AckError::Decode`]: crate::AckError::Decode
/// [`AckError::Timeout`]: crate::AckError::Timeout
/// [`AckError::Socket`]: crate::AckError::Socket
/// [`AckError::Socket(SocketError::Closed)`]: crate::SocketError::Closed
Expand Down Expand Up @@ -719,13 +719,13 @@ impl<A: Adapter> BroadcastOperators<A> {
///
/// If the client didn't respond before the timeout, the [`AckStream`] will yield
/// an [`AckError::Timeout`]. If the data sent by the client is not deserializable as `V`,
/// an [`AckError::Serde`] will be yielded.
/// an [`AckError::Decode`] will be yielded.
///
/// [`timeout()`]: #method.timeout
/// [`Stream`]: futures_core::stream::Stream
/// [`Future`]: futures_core::future::Future
/// [`AckResponse`]: crate::ack::AckResponse
/// [`AckError::Serde`]: crate::AckError::Serde
/// [`AckError::Decode`]: crate::AckError::Decode
/// [`AckError::Timeout`]: crate::AckError::Timeout
/// [`AckError::Socket`]: crate::AckError::Socket
/// [`AckError::Socket(SocketError::Closed)`]: crate::SocketError::Closed
Expand Down
4 changes: 2 additions & 2 deletions crates/socketioxide/src/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,14 +350,14 @@ impl<A: Adapter> Socket<A> {
///
/// If the client didn't respond before the timeout, the [`AckStream`] will yield
/// an [`AckError::Timeout`]. If the data sent by the client is not deserializable as `V`,
/// an [`AckError::Serde`] will be yielded.
/// an [`AckError::Decode`] will be yielded.
///
/// [`timeout()`]: crate::operators::ConfOperators#method.timeout
/// [`SocketIoBuilder::ack_timeout`]: crate::SocketIoBuilder#method.ack_timeout
/// [`Stream`]: futures_core::stream::Stream
/// [`Future`]: futures_core::future::Future
/// [`AckError`]: crate::AckError
/// [`AckError::Serde`]: crate::AckError::Serde
/// [`AckError::Decode`]: crate::AckError::Decode
/// [`AckError::Timeout`]: crate::AckError::Timeout
/// [`AckError::Socket`]: crate::AckError::Socket
/// [`AckError::Socket(SocketError::Closed)`]: crate::SocketError::Closed
Expand Down

0 comments on commit a94a32f

Please sign in to comment.