socketioxide_core/
parser.rs

1//! Contains all the type and interfaces for the parser sub-crates.
2//!
3//! The parsing system in socketioxide is split in three phases for serialization and deserialization:
4//!
5//! ## Deserialization
6//! * The SocketIO server receives a packet and calls [`Parse::decode_str`] or [`Parse::decode_bin`]
7//!   to decode the incoming packet. If a [`ParseError::NeedsMoreBinaryData`] is returned, the server keeps the packet
8//!   and waits for new incoming data.
9//! * Once the packet is complete, the server dispatches the packet to the appropriate namespace
10//!   and calls [`Parse::read_event`] to route the data to the appropriate event handler.
11//! * If the user-provided handler has a `Data` extractor with a provided `T` type, the server
12//!   calls [`Parse::decode_value`] to deserialize the data. This function will handle the event
13//!   name as the first argument of the array, as well as variadic arguments.
14//!
15//! ## Serialization
16//! * The user calls emit from the socket or namespace with custom `Serializable` data. The server calls
17//!   [`Parse::encode_value`] to convert this to a raw [`Value`] to be included in the packet. The function
18//!   will take care of handling the event name as the first argument of the array, along with variadic arguments.
19//! * The server then calls [`Parse::encode`] to convert the payload provided by the user,
20//!   along with other metadata (namespace, ack ID, etc.), into a fully serialized packet ready to be sent.
21
22use std::{
23    fmt,
24    sync::{atomic::AtomicUsize, Mutex},
25};
26
27use bytes::Bytes;
28use engineioxide::Str;
29use serde::{de::Visitor, ser::Impossible, Deserialize, Serialize};
30
31use crate::{packet::Packet, Value};
32
33/// The parser state that is shared between the parser and the socket.io system.
34/// Used to handle partial binary packets when receiving binary packets that have
35/// adjacent binary attachments
36#[derive(Debug, Default)]
37pub struct ParserState {
38    /// Partial binary packet that is being received
39    /// Stored here until all the binary payloads are received for common parser
40    pub partial_bin_packet: Mutex<Option<Packet>>,
41
42    /// The number of expected binary attachments (used when receiving data for common parser)
43    pub incoming_binary_cnt: AtomicUsize,
44}
45
46/// All socket.io parser should implement this trait.
47/// Parsers should be stateless.
48pub trait Parse: Default + Copy {
49    /// The error produced when encoding a packet
50    type EncodeError: std::error::Error;
51    /// The error produced when decoding a packet
52    type DecodeError: std::error::Error;
53
54    /// Convert a packet into multiple payloads to be sent.
55    fn encode(self, packet: Packet) -> Value;
56
57    /// Parse a given input string. If the payload needs more adjacent binary packet,
58    /// the partial packet will be kept and a [`ParseError::NeedsMoreBinaryData`] will be returned.
59    fn decode_str(
60        self,
61        state: &ParserState,
62        data: Str,
63    ) -> Result<Packet, ParseError<Self::DecodeError>>;
64
65    /// Parse a given input binary. If the payload needs more adjacent binary packet,
66    /// the partial packet is still kept and a [`ParseError::NeedsMoreBinaryData`] will be returned.
67    fn decode_bin(
68        self,
69        state: &ParserState,
70        bin: Bytes,
71    ) -> Result<Packet, ParseError<Self::DecodeError>>;
72
73    /// Convert any serializable data to a generic [`Value`] to be later included as a payload in the packet.
74    ///
75    /// * Any data serialized will be wrapped in an array to match the socket.io format (`[data]`).
76    /// * If the data is a tuple-like type the tuple will be expanded in the array (`[...data]`).
77    /// * If provided the event name will be serialized as the first element of the array
78    ///   (`[event, ...data]`) or (`[event, data]`).
79    fn encode_value<T: ?Sized + Serialize>(
80        self,
81        data: &T,
82        event: Option<&str>,
83    ) -> Result<Value, Self::EncodeError>;
84
85    /// Convert any generic [`Value`] to a deserializable type.
86    /// It should always be an array (according to the serde model).
87    ///
88    /// * If `with_event` is true, we expect an event str as the first element and we will skip
89    ///   it when deserializing data.
90    /// * If `T` is a tuple-like type, all the remaining elements of the array will be
91    ///   deserialized (`[...data]`).
92    /// * If `T` is not a tuple-like type, the first element of the array will be deserialized (`[data]`).
93    fn decode_value<'de, T: Deserialize<'de>>(
94        self,
95        value: &'de mut Value,
96        with_event: bool,
97    ) -> Result<T, Self::DecodeError>;
98
99    /// Convert any generic [`Value`] to a type with the default serde impl without binary + event tricks.
100    /// This is mainly used for connect payloads.
101    fn decode_default<'de, T: Deserialize<'de>>(
102        self,
103        value: Option<&'de Value>,
104    ) -> Result<T, Self::DecodeError>;
105
106    /// Convert any type to a generic [`Value`] with the default serde impl without binary + event tricks.
107    /// This is mainly used for connect payloads.
108    fn encode_default<T: ?Sized + Serialize>(self, data: &T) -> Result<Value, Self::EncodeError>;
109
110    /// Try to read the event name from the given payload data.
111    /// The event name should be the first element of the provided array according to the serde model.
112    fn read_event(self, value: &Value) -> Result<&str, Self::DecodeError>;
113}
114
115/// Errors when parsing/serializing socket.io packets
116#[derive(thiserror::Error, Debug)]
117pub enum ParseError<E: std::error::Error> {
118    /// Invalid packet type
119    #[error("invalid packet type")]
120    InvalidPacketType,
121
122    /// Invalid ack id
123    #[error("invalid ack id")]
124    InvalidAckId,
125
126    /// Invalid event name
127    #[error("invalid event name")]
128    InvalidEventName,
129
130    /// Invalid data
131    #[error("invalid data")]
132    InvalidData,
133
134    /// Invalid namespace
135    #[error("invalid namespace")]
136    InvalidNamespace,
137
138    /// Invalid attachments
139    #[error("invalid attachments")]
140    InvalidAttachments,
141
142    /// Received unexpected binary data
143    #[error(
144        "received unexpected binary data. Make sure you are using the same parser on both ends."
145    )]
146    UnexpectedBinaryPacket,
147
148    /// Received unexpected string data
149    #[error(
150        "received unexpected string data. Make sure you are using the same parser on both ends."
151    )]
152    UnexpectedStringPacket,
153
154    /// Needs more binary data before deserialization. It is not exactly an error, it is used for control flow,
155    /// e.g the common parser needs adjacent binary packets and therefore will returns
156    /// `NeedsMoreBinaryData` n times for n adjacent binary packet expected.
157    ///
158    /// In this case the user should call again the parser with the next binary payload.
159    #[error("needs more binary data for packet completion")]
160    NeedsMoreBinaryData,
161
162    /// The inner parser error
163    #[error("parser error: {0:?}")]
164    ParserError(#[from] E),
165}
166impl<E: std::error::Error> ParseError<E> {
167    /// Wrap the [`ParseError::ParserError`] variant with a new error type
168    pub fn wrap_err<E1: std::error::Error>(self, f: impl FnOnce(E) -> E1) -> ParseError<E1> {
169        match self {
170            Self::ParserError(e) => ParseError::ParserError(f(e)),
171            ParseError::InvalidPacketType => ParseError::InvalidPacketType,
172            ParseError::InvalidAckId => ParseError::InvalidAckId,
173            ParseError::InvalidEventName => ParseError::InvalidEventName,
174            ParseError::InvalidData => ParseError::InvalidData,
175            ParseError::InvalidNamespace => ParseError::InvalidNamespace,
176            ParseError::InvalidAttachments => ParseError::InvalidAttachments,
177            ParseError::UnexpectedBinaryPacket => ParseError::UnexpectedBinaryPacket,
178            ParseError::UnexpectedStringPacket => ParseError::UnexpectedStringPacket,
179            ParseError::NeedsMoreBinaryData => ParseError::NeedsMoreBinaryData,
180        }
181    }
182}
183
184/// A seed that can be used to deserialize only the 1st element of a sequence
185pub struct FirstElement<T>(std::marker::PhantomData<T>);
186impl<T> Default for FirstElement<T> {
187    fn default() -> Self {
188        Self(Default::default())
189    }
190}
191impl<'de, T: serde::Deserialize<'de>> serde::de::Visitor<'de> for FirstElement<T> {
192    type Value = T;
193
194    fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
195        write!(formatter, "a sequence in which we care about first element",)
196    }
197
198    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
199    where
200        A: serde::de::SeqAccess<'de>,
201    {
202        use serde::de::Error;
203        let data = seq
204            .next_element::<T>()?
205            .ok_or(A::Error::custom("first element not found"));
206
207        // Consume the rest of the sequence
208        while seq.next_element::<serde::de::IgnoredAny>()?.is_some() {}
209
210        data
211    }
212}
213
214impl<'de, T: serde::Deserialize<'de>> serde::de::DeserializeSeed<'de> for FirstElement<T> {
215    type Value = T;
216
217    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
218    where
219        D: serde::Deserializer<'de>,
220    {
221        deserializer.deserialize_seq(self)
222    }
223}
224
225/// Serializer and deserializer that simply return if the root object is a tuple or not.
226/// It is used with [`is_de_tuple`] and [`is_ser_tuple`].
227/// Thanks to this information we can expand tuple data into multiple arguments
228/// while serializing vectors as a single value.
229struct IsTupleSerde;
230#[derive(Debug)]
231struct IsTupleSerdeError(bool);
232impl fmt::Display for IsTupleSerdeError {
233    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
234        write!(f, "IsTupleSerializerError: {}", self.0)
235    }
236}
237impl std::error::Error for IsTupleSerdeError {}
238impl serde::ser::Error for IsTupleSerdeError {
239    fn custom<T: fmt::Display>(_msg: T) -> Self {
240        IsTupleSerdeError(false)
241    }
242}
243impl serde::de::Error for IsTupleSerdeError {
244    fn custom<T: fmt::Display>(_msg: T) -> Self {
245        IsTupleSerdeError(false)
246    }
247}
248
249impl<'de> serde::Deserializer<'de> for IsTupleSerde {
250    type Error = IsTupleSerdeError;
251
252    serde::forward_to_deserialize_any! {
253        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
254        string unit unit_struct seq  map
255        struct enum identifier ignored_any bytes byte_buf option
256    }
257
258    fn deserialize_any<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value, Self::Error> {
259        Err(IsTupleSerdeError(false))
260    }
261
262    fn deserialize_tuple<V: Visitor<'de>>(
263        self,
264        _len: usize,
265        _visitor: V,
266    ) -> Result<V::Value, Self::Error> {
267        Err(IsTupleSerdeError(true))
268    }
269
270    fn deserialize_tuple_struct<V: Visitor<'de>>(
271        self,
272        _name: &'static str,
273        _len: usize,
274        _visitor: V,
275    ) -> Result<V::Value, Self::Error> {
276        Err(IsTupleSerdeError(true))
277    }
278
279    fn deserialize_newtype_struct<V: Visitor<'de>>(
280        self,
281        _name: &'static str,
282        _visitor: V,
283    ) -> Result<V::Value, Self::Error> {
284        Err(IsTupleSerdeError(true))
285    }
286}
287
288impl serde::Serializer for IsTupleSerde {
289    type Ok = bool;
290    type Error = IsTupleSerdeError;
291    type SerializeSeq = Impossible<bool, IsTupleSerdeError>;
292    type SerializeTuple = Impossible<bool, IsTupleSerdeError>;
293    type SerializeTupleStruct = Impossible<bool, IsTupleSerdeError>;
294    type SerializeTupleVariant = Impossible<bool, IsTupleSerdeError>;
295    type SerializeMap = Impossible<bool, IsTupleSerdeError>;
296    type SerializeStruct = Impossible<bool, IsTupleSerdeError>;
297    type SerializeStructVariant = Impossible<bool, IsTupleSerdeError>;
298
299    fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
300        Ok(false)
301    }
302
303    fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
304        Ok(false)
305    }
306
307    fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
308        Ok(false)
309    }
310
311    fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
312        Ok(false)
313    }
314
315    fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
316        Ok(false)
317    }
318
319    fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
320        Ok(false)
321    }
322
323    fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
324        Ok(false)
325    }
326
327    fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
328        Ok(false)
329    }
330
331    fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
332        Ok(false)
333    }
334
335    fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
336        Ok(false)
337    }
338
339    fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
340        Ok(false)
341    }
342
343    fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
344        Ok(false)
345    }
346
347    fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> {
348        Ok(false)
349    }
350
351    fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
352        Ok(false)
353    }
354
355    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
356        Ok(false)
357    }
358
359    fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
360    where
361        T: ?Sized + serde::Serialize,
362    {
363        Ok(false)
364    }
365
366    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
367        Ok(false)
368    }
369
370    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
371        Ok(false)
372    }
373
374    fn serialize_unit_variant(
375        self,
376        _name: &'static str,
377        _variant_index: u32,
378        _variant: &'static str,
379    ) -> Result<Self::Ok, Self::Error> {
380        Ok(false)
381    }
382
383    fn serialize_newtype_struct<T>(
384        self,
385        _name: &'static str,
386        _value: &T,
387    ) -> Result<Self::Ok, Self::Error>
388    where
389        T: ?Sized + serde::Serialize,
390    {
391        Ok(true)
392    }
393
394    fn serialize_newtype_variant<T>(
395        self,
396        _name: &'static str,
397        _variant_index: u32,
398        _variant: &'static str,
399        _value: &T,
400    ) -> Result<Self::Ok, Self::Error>
401    where
402        T: ?Sized + serde::Serialize,
403    {
404        Ok(false)
405    }
406
407    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
408        Err(IsTupleSerdeError(false))
409    }
410
411    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
412        Err(IsTupleSerdeError(true))
413    }
414
415    fn serialize_tuple_struct(
416        self,
417        _name: &'static str,
418        _len: usize,
419    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
420        Err(IsTupleSerdeError(true))
421    }
422
423    fn serialize_tuple_variant(
424        self,
425        _name: &'static str,
426        _variant_index: u32,
427        _variant: &'static str,
428        _len: usize,
429    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
430        Err(IsTupleSerdeError(false))
431    }
432
433    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
434        Err(IsTupleSerdeError(false))
435    }
436
437    fn serialize_struct(
438        self,
439        _name: &'static str,
440        _len: usize,
441    ) -> Result<Self::SerializeStruct, Self::Error> {
442        Err(IsTupleSerdeError(false))
443    }
444
445    fn serialize_struct_variant(
446        self,
447        _name: &'static str,
448        _variant_index: u32,
449        _variant: &'static str,
450        _len: usize,
451    ) -> Result<Self::SerializeStructVariant, Self::Error> {
452        Err(IsTupleSerdeError(false))
453    }
454}
455
456/// Returns true if the value is a tuple-like type according to the serde model.
457pub fn is_ser_tuple<T: ?Sized + serde::Serialize>(value: &T) -> bool {
458    match value.serialize(IsTupleSerde) {
459        Ok(v) | Err(IsTupleSerdeError(v)) => v,
460    }
461}
462
463/// Returns true if the type is a tuple-like type according to the serde model.
464pub fn is_de_tuple<'de, T: serde::Deserialize<'de>>() -> bool {
465    match T::deserialize(IsTupleSerde) {
466        Ok(_) => unreachable!(),
467        Err(IsTupleSerdeError(v)) => v,
468    }
469}
470#[cfg(test)]
471mod test {
472    use super::*;
473    use serde::{Deserialize, Serialize};
474
475    #[test]
476    fn is_tuple() {
477        assert!(is_ser_tuple(&(1, 2, 3)));
478        assert!(is_de_tuple::<(usize, usize, usize)>());
479
480        assert!(is_ser_tuple(&[1, 2, 3]));
481        assert!(is_de_tuple::<[usize; 3]>());
482
483        #[derive(Serialize, Deserialize)]
484        struct TupleStruct<'a>(&'a str);
485        assert!(is_ser_tuple(&TupleStruct("test")));
486        assert!(is_de_tuple::<TupleStruct<'_>>());
487
488        assert!(!is_ser_tuple(&vec![1, 2, 3]));
489        assert!(!is_de_tuple::<Vec<usize>>());
490
491        #[derive(Serialize, Deserialize)]
492        struct UnitStruct;
493        assert!(!is_ser_tuple(&UnitStruct));
494        assert!(!is_de_tuple::<UnitStruct>());
495    }
496}