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