redis_asyncx/
frame.rs

1//! Implements the [RESP3](https://redis.io/docs/latest/develop/reference/protocol-spec)
2//! serialization protocol for Redis client-server communication.
3
4use crate::{RedisError, Result};
5// use anyhow::Ok; // Removed as it conflicts with the Result type in your crate
6use bytes::{Buf, Bytes, BytesMut};
7use std::io::{BufRead, Cursor};
8
9#[derive(Debug, PartialEq)]
10pub struct BigInt {
11    sign: bool,
12    data: Vec<u8>,
13}
14
15/// Frame represents a single RESP data transmit unit over the socket.
16///
17/// more on the RESP protocol can be found [here](https://redis.io/topics/protocol)
18#[derive(Debug, PartialEq)]
19pub enum Frame {
20    SimpleString(String),
21    SimpleError(String),
22    Integer(i64),
23    BulkString(Bytes),
24    Array(Vec<Frame>),
25    Null,
26    Boolean(bool),
27    Double(f64),
28    BigNumber(BigInt),
29    BulkError(Bytes),
30    // first: encoding, second: data payload
31    VerbatimString(Bytes, Bytes),
32    Map(Vec<(Frame, Frame)>),
33    Attribute,
34    Set(Vec<Frame>),
35    Push,
36}
37
38impl Frame {
39    /// Returns an empty Array Frame.
40    pub const fn array() -> Self {
41        Frame::Array(Vec::new())
42    }
43
44    /// A utility method to push a Frame into an Array/Set Frame.
45    ///
46    /// # Arguments
47    ///
48    /// * `frame` - A Frame to be pushed into the Array
49    ///
50    /// # Panics
51    ///
52    /// This method will panic if the Frame is not an Array or Set.
53    pub fn push_frame_to_array(&mut self, frame: Frame) -> Result<()> {
54        match self {
55            Frame::Array(vec) => {
56                vec.push(frame);
57                Ok(())
58            }
59            Frame::Set(vec) => {
60                vec.push(frame);
61                Ok(())
62            }
63            _ => Err(RedisError::Unknown),
64        }
65    }
66
67    /// A utility method to push a Frame into a Map Frame.
68    ///
69    /// # Arguments
70    ///
71    /// * `key` - A Frame to be used as a key in the Map
72    /// * `value` - A Frame to be used as a value in the Map
73    ///
74    /// # Panics
75    ///
76    /// This method will panic if the Frame is not a Map.
77    pub fn push_frame_to_map(&mut self, key: Frame, value: Frame) -> Result<()> {
78        match self {
79            Frame::Map(vec) => {
80                vec.push((key, value));
81                Ok(())
82            }
83            _ => Err(RedisError::Unknown),
84        }
85    }
86
87    /// Serializes a Frame into a bytes buffer.
88    ///
89    /// The returned value is a smart pointer only counting reference. It is cheap to clone.
90    /// Caller can get the underlying slice by calling `as_slice` or `as_ref` on the returned value.
91    /// It is almost 0 cost to get the slice.
92    ///
93    /// # Returns
94    ///
95    /// A Result containing the serialized bytes buffer
96    pub async fn serialize(&self) -> Result<Bytes> {
97        match self {
98            Frame::SimpleString(val) => {
99                let mut buf = BytesMut::with_capacity(val.len() + 3);
100
101                // + indicates it is a simple string
102                buf.extend_from_slice(b"+");
103                // encode the string value
104                buf.extend_from_slice(val.as_bytes());
105                buf.extend_from_slice(b"\r\n");
106
107                Ok(buf.freeze()) // Ensure this uses the crate's Result type
108            }
109            Frame::SimpleError(val) => {
110                let mut buf = BytesMut::with_capacity(val.len() + 3);
111
112                // - indicates it is an error
113                buf.extend_from_slice(b"-");
114                // encode the error message
115                buf.extend_from_slice(val.as_bytes());
116                buf.extend_from_slice(b"\r\n");
117
118                Ok(buf.freeze())
119            }
120            Frame::Integer(val) => {
121                let mut buf = BytesMut::with_capacity(20);
122
123                // : indicates it is an integer
124                buf.extend_from_slice(b":");
125                // encode the integer value
126                buf.extend_from_slice(val.to_string().as_bytes());
127                buf.extend_from_slice(b"\r\n");
128
129                Ok(buf.freeze())
130            }
131            Frame::BulkString(val) => {
132                let mut buf = BytesMut::with_capacity(val.len() + 5);
133
134                // $ indicates it is a bulk string
135                buf.extend_from_slice(b"$");
136                // encode the length of the binary string
137                buf.extend_from_slice(val.len().to_string().as_bytes());
138                buf.extend_from_slice(b"\r\n");
139                // encode the binary string
140                buf.extend_from_slice(val.as_ref());
141                buf.extend_from_slice(b"\r\n");
142
143                Ok(buf.freeze())
144            }
145            Frame::Array(frame_vec) => {
146                let mut buf = BytesMut::new();
147
148                // * indicates it is an array
149                buf.extend_from_slice(b"*");
150                // encode the number of elements in the array
151                buf.extend_from_slice(frame_vec.len().to_string().as_bytes());
152                buf.extend_from_slice(b"\r\n");
153
154                // encode each element in the array
155                for frame in frame_vec {
156                    buf.extend_from_slice(&Box::pin(frame.serialize()).await?);
157                }
158
159                Ok(buf.freeze())
160            }
161            Frame::Null => {
162                let mut buf = BytesMut::with_capacity(3);
163
164                // _ indicates it is a null
165                buf.extend_from_slice(b"_\r\n");
166
167                Ok(buf.freeze())
168            }
169            Frame::Boolean(val) => {
170                let mut buf: BytesMut = BytesMut::with_capacity(3);
171
172                // # indicates it is a boolean
173                buf.extend_from_slice(b"#");
174                // encode the boolean value
175                buf.extend_from_slice(if *val { b"t" } else { b"f" });
176                buf.extend_from_slice(b"\r\n");
177
178                Ok(buf.freeze())
179            }
180            Frame::Double(val) => {
181                let mut buf: BytesMut = BytesMut::with_capacity(20);
182
183                // , indicates it is a double
184                buf.extend_from_slice(b",");
185
186                // encode the double value
187                if val.is_nan() {
188                    buf.extend_from_slice(b"nan");
189                } else {
190                    match *val {
191                        f64::INFINITY => buf.extend_from_slice(b"inf"),
192                        f64::NEG_INFINITY => buf.extend_from_slice(b"-inf"),
193                        _ => {
194                            buf.extend_from_slice(val.to_string().as_bytes());
195                        }
196                    }
197                }
198
199                // append \r\n to the end of the buffer
200                buf.extend_from_slice(b"\r\n");
201
202                Ok(buf.freeze())
203            }
204            Frame::BigNumber(val) => {
205                todo!("BigNumber serialization is not implemented yet {:?}", val)
206            }
207            Frame::BulkError(val) => {
208                let mut buf = BytesMut::with_capacity(val.len() + 5);
209
210                // ! indicates it is a bulk error
211                buf.extend_from_slice(b"!");
212                // encode the length of the binary string
213                buf.extend_from_slice(val.len().to_string().as_bytes());
214                buf.extend_from_slice(b"\r\n");
215                // encode the binary string
216                buf.extend_from_slice(val.as_ref());
217                buf.extend_from_slice(b"\r\n");
218
219                Ok(buf.freeze())
220            }
221            Frame::VerbatimString(encoding, val) => {
222                let mut buf: BytesMut = BytesMut::with_capacity(val.len() + 10);
223
224                // = indicates it is a verbatim string
225                buf.extend_from_slice(b"=");
226                // encode the length of the binary string
227                // +4 because encoding takes 3 bytes and : takes 1 byte
228                buf.extend_from_slice((val.len() + 4).to_string().as_bytes());
229                buf.extend_from_slice(b"\r\n");
230                // encode the encoding
231                buf.extend_from_slice(encoding.as_ref());
232                buf.extend_from_slice(b":");
233                // encode the binary string
234                buf.extend_from_slice(val.as_ref());
235                buf.extend_from_slice(b"\r\n");
236
237                Ok(buf.freeze())
238            }
239            Frame::Map(val) => {
240                let mut buf: BytesMut = BytesMut::new();
241
242                // % indicates it is a map
243                buf.extend_from_slice(b"%");
244                // encode the number of elements in the map
245                buf.extend_from_slice(val.len().to_string().as_bytes());
246                buf.extend_from_slice(b"\r\n");
247
248                // encode each element in the map
249                for (key, value) in val {
250                    buf.extend_from_slice(&Box::pin(key.serialize()).await?);
251                    buf.extend_from_slice(&Box::pin(value.serialize()).await?);
252                }
253
254                Ok(buf.freeze())
255            }
256            Frame::Attribute => {
257                todo!("Attribute serialization is not implemented yet")
258            }
259            Frame::Set(val) => {
260                let mut buf: BytesMut = BytesMut::new();
261
262                // ~ indicates it is a set
263                buf.extend_from_slice(b"~");
264                // encode the number of elements in the set
265                buf.extend_from_slice(val.len().to_string().as_bytes());
266                buf.extend_from_slice(b"\r\n");
267
268                // encode each element in the set
269                for frame in val {
270                    buf.extend_from_slice(&Box::pin(frame.serialize()).await?);
271                }
272
273                Ok(buf.freeze())
274            }
275            Frame::Push => {
276                todo!("Push serialization is not implemented yet")
277            }
278        }
279    }
280
281    /// Deserializes from the buffer into a Frame.
282    ///
283    /// The method reads from the buffer and parses it into a Frame.
284    ///
285    /// # Arguments
286    ///
287    /// * `buf` - An immutable read buffer containing the serialized Frame
288    ///
289    /// # Returns
290    ///
291    /// A Result containing the deserialized Frame
292    pub async fn deserialize(buf: Bytes) -> Result<Frame> {
293        // the cursor is almost zero cost as it is just a smart ptr to the buffer
294        Frame::try_parse(&mut Cursor::new(&buf[..]))
295    }
296
297    /// Tries parsing a Frame from the buffer.
298    ///
299    /// This method wraps the input with a cursor to track the current version as we need to make resursive calls.
300    /// Using a cursor avoids the need to split the buffer or passing an additional parameter.
301    ///
302    /// # Returns
303    ///
304    /// * `Ok(usize)` if the buffer contains a complete frame, the number of bytes needed to parse the frame
305    /// * `Err(RedisError::IncompleteFrame)` if the buffer contains an incomplete frame
306    /// * `Err(RedisError::InvalidFrame)` if the buffer contains an invalid frame
307    pub fn try_parse(cursor: &mut Cursor<&[u8]>) -> Result<Frame> {
308        if !cursor.has_remaining() {
309            return Err(RedisError::IncompleteFrame);
310        }
311
312        match cursor.get_u8() {
313            b'+' => {
314                // Simple string
315                let mut buf = String::new();
316                let _ = cursor.read_line(&mut buf).unwrap();
317
318                if buf.ends_with("\r\n") {
319                    Ok(Frame::SimpleString(
320                        buf.trim_end_matches("\r\n").to_string(),
321                    ))
322                } else {
323                    // fixme: there maybe edge cases here
324                    // we need to guarantee there's no more \r\n in the buffer
325                    Err(RedisError::IncompleteFrame)
326                }
327            }
328            b'-' => {
329                // Simple error
330                let mut buf = String::new();
331                let _ = cursor.read_line(&mut buf).unwrap();
332
333                if buf.ends_with("\r\n") {
334                    Ok(Frame::SimpleError(buf.trim_end_matches("\r\n").to_string()))
335                } else {
336                    // fixme: there maybe edge cases here
337                    // we need to guarantee there's no more \r\n in the buffer
338                    Err(RedisError::IncompleteFrame)
339                }
340            }
341            b':' => {
342                // Integer
343                let mut buf = String::new();
344                let _ = cursor.read_line(&mut buf).unwrap();
345
346                // todo: check whether it is a valid integer
347                if buf.ends_with("\r\n") {
348                    Ok(Frame::Integer(
349                        buf.trim_end_matches("\r\n").parse::<i64>().unwrap(),
350                    ))
351                } else {
352                    Err(RedisError::IncompleteFrame)
353                }
354            }
355            b'$' => {
356                // Bulk string
357                let mut buf = String::new();
358                // read the length of the bulk string
359                let _ = cursor.read_line(&mut buf).unwrap();
360
361                if !buf.ends_with("\r\n") {
362                    return Err(RedisError::IncompleteFrame);
363                }
364
365                let len: isize = buf.trim_end_matches("\r\n").parse::<isize>().unwrap();
366
367                // for RESP2, -1 indicates a null bulk string
368                if len == -1 {
369                    return Ok(Frame::Null);
370                }
371
372                // +2 because \r\n
373                if cursor.remaining() < len as usize + 2 {
374                    return Err(RedisError::IncompleteFrame);
375                }
376
377                let data = Bytes::copy_from_slice(&cursor.chunk()[..len as usize]);
378
379                // advance cursor
380                cursor.advance(len as usize + 2);
381
382                Ok(Frame::BulkString(data))
383            }
384            b'*' => {
385                // Array
386                let mut buf = String::new();
387                let _ = cursor.read_line(&mut buf).unwrap();
388
389                let len = buf.trim_end_matches("\r\n").parse::<usize>().unwrap();
390                let mut frame_vec: Vec<_> = Vec::with_capacity(len);
391
392                for _ in 0..len {
393                    frame_vec.push(Frame::try_parse(cursor)?);
394                }
395
396                Ok(Frame::Array(frame_vec))
397            }
398            b'_' => Ok(Frame::Null),
399            b'#' => {
400                // Boolean
401                let mut buf = String::new();
402                let _ = cursor.read_line(&mut buf).unwrap();
403
404                if buf.ends_with("\r\n") {
405                    let val = buf.trim_end_matches("\r\n");
406                    if val == "t" {
407                        Ok(Frame::Boolean(true))
408                    } else if val == "f" {
409                        Ok(Frame::Boolean(false))
410                    } else {
411                        Err(RedisError::InvalidFrame)
412                    }
413                } else {
414                    Err(RedisError::IncompleteFrame)
415                }
416            }
417            b',' => {
418                // Double
419                let mut buf = String::new();
420                let _ = cursor.read_line(&mut buf).unwrap();
421
422                if buf.ends_with("\r\n") {
423                    let val = buf.trim_end_matches("\r\n");
424                    if val == "nan" {
425                        Ok(Frame::Double(f64::NAN))
426                    } else if val == "inf" {
427                        Ok(Frame::Double(f64::INFINITY))
428                    } else if val == "-inf" {
429                        Ok(Frame::Double(f64::NEG_INFINITY))
430                    } else {
431                        Ok(Frame::Double(val.parse::<f64>().unwrap()))
432                    }
433                } else {
434                    Err(RedisError::IncompleteFrame)
435                }
436            }
437            b'(' => {
438                // Big number
439                todo!("Big number deserialization is not implemented yet")
440            }
441            b'!' => {
442                // Bulk error
443                let mut buf = String::new();
444                // read the length of the bulk string
445                let _ = cursor.read_line(&mut buf).unwrap();
446
447                if !buf.ends_with("\r\n") {
448                    return Err(RedisError::IncompleteFrame);
449                }
450
451                let len: isize = buf.trim_end_matches("\r\n").parse::<isize>().unwrap();
452
453                // for RESP2, -1 indicates a null bulk error
454                if len == -1 {
455                    return Ok(Frame::Null);
456                }
457
458                let len: usize = len.try_into().unwrap();
459
460                // +2 because \r\n
461                if cursor.remaining() < len + 2 {
462                    return Err(RedisError::IncompleteFrame);
463                }
464
465                // check if cursor ends with \r\n
466                if cursor.chunk()[len] != b'\r' || cursor.chunk()[len + 1] != b'\n' {
467                    return Err(RedisError::InvalidFrame);
468                }
469
470                let data = Bytes::copy_from_slice(&cursor.chunk()[..len]);
471
472                // advance cursor
473                cursor.advance(len + 2);
474
475                Ok(Frame::BulkError(data))
476            }
477            b'=' => {
478                // Verbatim string
479                let mut buf = String::new();
480                // read the length of the bulk string
481                let _ = cursor.read_line(&mut buf).unwrap();
482
483                if !buf.ends_with("\r\n") {
484                    return Err(RedisError::IncompleteFrame);
485                }
486
487                let len: usize = buf.trim_end_matches("\r\n").parse::<usize>().unwrap();
488
489                // +2 for \r\n
490                if cursor.remaining() < len + 2 {
491                    return Err(RedisError::IncompleteFrame);
492                }
493
494                // check if cursor ends with \r\n
495                if !cursor.chunk()[len..].starts_with(b"\r\n") {
496                    return Err(RedisError::InvalidFrame);
497                }
498
499                // read the encoding
500                let mut data = Bytes::copy_from_slice(&cursor.chunk()[..len]);
501
502                // split data into encoding and value, : as the delimiter
503                let encoding: Bytes = data.split_to(3);
504
505                // data[0] is b':', ignore it
506                data.advance(1);
507
508                // advance cursor
509                cursor.advance(len + 2);
510
511                Ok(Frame::VerbatimString(encoding, data))
512            }
513            b'%' => {
514                // Map
515                let mut buf = String::new();
516                let _ = cursor.read_line(&mut buf).unwrap();
517
518                let len = buf.trim_end_matches("\r\n").parse::<usize>().unwrap();
519                let mut frame_vec: Vec<_> = Vec::with_capacity(len);
520
521                for _ in 0..len {
522                    let key = Frame::try_parse(cursor)?;
523                    let value = Frame::try_parse(cursor)?;
524                    frame_vec.push((key, value));
525                }
526
527                Ok(Frame::Map(frame_vec))
528            }
529            b'&' => {
530                // Attribute
531                todo!("Attribute deserialization is not implemented yet")
532            }
533            b'~' => {
534                // Set
535                let mut buf = String::new();
536                let _ = cursor.read_line(&mut buf).unwrap();
537
538                let len = buf.trim_end_matches("\r\n").parse::<usize>().unwrap();
539                let mut frame_vec: Vec<_> = Vec::with_capacity(len);
540
541                for _ in 0..len {
542                    frame_vec.push(Frame::try_parse(cursor)?);
543                }
544
545                Ok(Frame::Set(frame_vec))
546            }
547            b'>' => {
548                // Push
549                todo!("Push deserialization is not implemented yet")
550            }
551            _ => Err(RedisError::InvalidFrame),
552        }
553    }
554}
555
556#[cfg(test)]
557mod tests {
558    use super::*;
559
560    /// Tests the serialization of a simple string frame.
561    #[tokio::test]
562    async fn test_serialize_simple_string() {
563        let frame = Frame::SimpleString("OK".to_string());
564        let bytes = frame.serialize().await.unwrap();
565
566        assert_eq!(bytes, Bytes::from_static(b"+OK\r\n"));
567    }
568
569    /// Tests the serialization of a simple error frame.
570    #[tokio::test]
571    async fn test_serialize_simple_error() {
572        let frame = Frame::SimpleError("ERR".to_string());
573        let bytes = frame.serialize().await.unwrap();
574
575        assert_eq!(bytes, Bytes::from_static(b"-ERR\r\n"));
576    }
577
578    /// Tests the serialization of an integer frame.
579    #[tokio::test]
580    async fn test_serialize_integer() {
581        // positive integer
582        let frame = Frame::Integer(123_i64);
583        let bytes = frame.serialize().await.unwrap();
584
585        assert_eq!(bytes, Bytes::from_static(b":123\r\n"));
586
587        // negative integer
588        let frame = Frame::Integer(-123_i64);
589        let bytes = frame.serialize().await.unwrap();
590
591        assert_eq!(bytes, Bytes::from_static(b":-123\r\n"));
592    }
593
594    /// Tests the serialization of a bulk string frame.
595    #[tokio::test]
596    async fn test_serialize_bulk_string() {
597        let frame = Frame::BulkString(Bytes::from_static(b"Hello Redis"));
598        let bytes = frame.serialize().await.unwrap();
599
600        assert_eq!(bytes, Bytes::from_static(b"$11\r\nHello Redis\r\n"));
601
602        // empty bulk string
603        let frame = Frame::BulkString(Bytes::from_static(b""));
604        let bytes = frame.serialize().await.unwrap();
605
606        assert_eq!(bytes, Bytes::from_static(b"$0\r\n\r\n"));
607    }
608
609    /// Tests the serailization of an array frame.
610    #[tokio::test]
611    async fn test_serialize_array() {
612        let mut frame = Frame::array();
613        frame
614            .push_frame_to_array(Frame::BulkString(Bytes::from_static(b"Hello")))
615            .unwrap();
616        frame
617            .push_frame_to_array(Frame::BulkString(Bytes::from_static(b"Redis")))
618            .unwrap();
619
620        let bytes = frame.serialize().await.unwrap();
621
622        assert_eq!(
623            bytes,
624            Bytes::from_static(b"*2\r\n$5\r\nHello\r\n$5\r\nRedis\r\n")
625        );
626
627        // empty array
628        let frame = Frame::array();
629        let bytes = frame.serialize().await.unwrap();
630
631        assert_eq!(bytes, Bytes::from_static(b"*0\r\n"));
632
633        // nested array
634        let mut frame: Frame = Frame::array();
635        let mut nested_frame = Frame::array();
636        nested_frame
637            .push_frame_to_array(Frame::BulkString(Bytes::from_static(b"Hello")))
638            .unwrap();
639        nested_frame
640            .push_frame_to_array(Frame::BulkString(Bytes::from_static(b"Redis")))
641            .unwrap();
642
643        if let Frame::Array(vec) = &mut frame {
644            vec.push(nested_frame);
645        }
646
647        let bytes = frame.serialize().await.unwrap();
648
649        assert_eq!(
650            bytes,
651            Bytes::from_static(b"*1\r\n*2\r\n$5\r\nHello\r\n$5\r\nRedis\r\n")
652        );
653    }
654
655    /// Tests the serialization of a null frame.
656    #[tokio::test]
657    async fn test_serialize_null() {
658        let frame = Frame::Null;
659        let bytes = frame.serialize().await.unwrap();
660
661        assert_eq!(bytes, Bytes::from_static(b"_\r\n"));
662    }
663
664    /// Tests the serialization of a boolean frame.
665    #[tokio::test]
666    async fn test_serialize_boolean() {
667        let frame = Frame::Boolean(true);
668        let bytes = frame.serialize().await.unwrap();
669
670        assert_eq!(bytes, Bytes::from_static(b"#t\r\n"));
671
672        let frame = Frame::Boolean(false);
673        let bytes = frame.serialize().await.unwrap();
674
675        assert_eq!(bytes, Bytes::from_static(b"#f\r\n"));
676    }
677
678    // Tests the serialization of a double frame.
679    #[tokio::test]
680    async fn test_serialize_double() {
681        let frame = Frame::Double(123.456);
682        let bytes = frame.serialize().await.unwrap();
683
684        assert_eq!(bytes, Bytes::from_static(b",123.456\r\n"));
685
686        let frame = Frame::Double(f64::NAN);
687        let bytes = frame.serialize().await.unwrap();
688
689        assert_eq!(bytes, Bytes::from_static(b",nan\r\n"));
690
691        let frame = Frame::Double(f64::INFINITY);
692        let bytes = frame.serialize().await.unwrap();
693
694        assert_eq!(bytes, Bytes::from_static(b",inf\r\n"));
695
696        let frame = Frame::Double(f64::NEG_INFINITY);
697        let bytes = frame.serialize().await.unwrap();
698
699        assert_eq!(bytes, Bytes::from_static(b",-inf\r\n"));
700    }
701
702    /// Tests the serialization of a bulk error frame.
703    #[tokio::test]
704    async fn test_serialize_bulk_error() {
705        let frame = Frame::BulkError(Bytes::from_static(b"Hello Redis"));
706        let bytes = frame.serialize().await.unwrap();
707
708        assert_eq!(bytes, Bytes::from_static(b"!11\r\nHello Redis\r\n"));
709
710        // empty bulk error
711        let frame = Frame::BulkError(Bytes::from_static(b""));
712        let bytes = frame.serialize().await.unwrap();
713
714        assert_eq!(bytes, Bytes::from_static(b"!0\r\n\r\n"));
715    }
716
717    /// Tests the serialization of a verbatim string frame.
718    #[tokio::test]
719    async fn test_serialize_verbatim_string() {
720        let frame = Frame::VerbatimString(
721            Bytes::from_static(b"txt"),
722            Bytes::from_static(b"Some string"),
723        );
724        let bytes = frame.serialize().await.unwrap();
725
726        assert_eq!(bytes, Bytes::from_static(b"=15\r\ntxt:Some string\r\n"));
727
728        // empty verbatim string
729        let frame = Frame::VerbatimString(Bytes::from_static(b"txt"), Bytes::from_static(b""));
730        let bytes = frame.serialize().await.unwrap();
731
732        assert_eq!(bytes, Bytes::from_static(b"=4\r\ntxt:\r\n"));
733    }
734
735    /// Tests the serialization of a map frame.
736    #[tokio::test]
737    async fn test_serialize_map() {
738        let mut frame: Frame = Frame::Map(Vec::new());
739        frame
740            .push_frame_to_map(
741                Frame::SimpleString("key".to_string()),
742                Frame::SimpleString("value".to_string()),
743            )
744            .unwrap();
745
746        let bytes = frame.serialize().await.unwrap();
747
748        assert_eq!(bytes, Bytes::from_static(b"%1\r\n+key\r\n+value\r\n"));
749    }
750
751    /// Tests the serialization of a set frame.
752    #[tokio::test]
753    async fn test_serialize_set() {
754        let mut frame: Frame = Frame::Set(Vec::new());
755        frame
756            .push_frame_to_array(Frame::BulkString(Bytes::from_static(b"Hello")))
757            .unwrap();
758        frame
759            .push_frame_to_array(Frame::BulkString(Bytes::from_static(b"Redis")))
760            .unwrap();
761
762        let bytes = frame.serialize().await.unwrap();
763
764        assert_eq!(
765            bytes,
766            Bytes::from_static(b"~2\r\n$5\r\nHello\r\n$5\r\nRedis\r\n")
767        );
768    }
769
770    /// Tests the deserialization of a simple string frame.
771    #[tokio::test]
772    async fn test_deserialize_simple_string() {
773        let bytes = Bytes::from_static(b"+OK\r\n");
774
775        let frame = Frame::deserialize(bytes).await.unwrap();
776
777        assert_eq!(frame, Frame::SimpleString("OK".to_string()));
778    }
779
780    /// Tests the deserialization of a simple error frame.
781    #[tokio::test]
782    async fn test_deserialize_simple_error() {
783        let bytes = Bytes::from_static(b"-ERR\r\n");
784
785        let frame = Frame::deserialize(bytes).await.unwrap();
786
787        assert_eq!(frame, Frame::SimpleError("ERR".to_string()));
788    }
789
790    /// Tests the deserialization of an integer frame.
791    #[tokio::test]
792    async fn test_deserialize_integer() {
793        // positive integer
794        let bytes = Bytes::from_static(b":123\r\n");
795
796        let frame = Frame::deserialize(bytes).await.unwrap();
797
798        assert_eq!(frame, Frame::Integer(123_i64));
799
800        // negative integer
801        let bytes = Bytes::from_static(b":-123\r\n");
802
803        let frame = Frame::deserialize(bytes).await.unwrap();
804
805        assert_eq!(frame, Frame::Integer(-123_i64));
806    }
807
808    /// Tests the deserialization of a bulk string frame.
809    #[tokio::test]
810    async fn test_deserialize_bulk_string() {
811        let bytes = Bytes::from_static(b"$11\r\nHello Redis\r\n");
812
813        let frame = Frame::deserialize(bytes).await.unwrap();
814
815        assert_eq!(frame, Frame::BulkString(Bytes::from_static(b"Hello Redis")));
816
817        let bytes = Bytes::from_static(b"$0\r\n\r\n");
818
819        let frame = Frame::deserialize(bytes).await.unwrap();
820
821        assert_eq!(frame, Frame::BulkString(Bytes::from_static(b"")));
822    }
823
824    /// Tests deseaialization of an array frame.
825    #[tokio::test]
826    async fn test_deserialize_array() {
827        let bytes = Bytes::from_static(b"*2\r\n$5\r\nHello\r\n$5\r\nRedis\r\n");
828
829        let frame = Frame::deserialize(bytes).await.unwrap();
830
831        let mut expected_frame = Frame::array();
832        expected_frame
833            .push_frame_to_array(Frame::BulkString(Bytes::from_static(b"Hello")))
834            .unwrap();
835        expected_frame
836            .push_frame_to_array(Frame::BulkString(Bytes::from_static(b"Redis")))
837            .unwrap();
838
839        assert_eq!(frame, expected_frame);
840
841        // empty array
842        let bytes = Bytes::from_static(b"*0\r\n");
843
844        let frame = Frame::deserialize(bytes).await.unwrap();
845
846        assert_eq!(frame, Frame::array());
847
848        // nested array
849        let bytes = Bytes::from_static(b"*1\r\n*2\r\n$5\r\nHello\r\n$5\r\nRedis\r\n");
850
851        let frame = Frame::deserialize(bytes).await.unwrap();
852
853        let mut expected_frame = Frame::array();
854        let mut nested_frame = Frame::array();
855        nested_frame
856            .push_frame_to_array(Frame::BulkString(Bytes::from_static(b"Hello")))
857            .unwrap();
858        nested_frame
859            .push_frame_to_array(Frame::BulkString(Bytes::from_static(b"Redis")))
860            .unwrap();
861
862        expected_frame.push_frame_to_array(nested_frame).unwrap();
863
864        assert_eq!(frame, expected_frame);
865    }
866
867    /// Tests the deserialization of a null frame.
868    #[tokio::test]
869    async fn test_deserialize_null() {
870        let bytes = Bytes::from_static(b"_\r\n");
871
872        let frame = Frame::deserialize(bytes).await.unwrap();
873
874        assert_eq!(frame, Frame::Null);
875    }
876
877    /// Tests the deserialization of a boolean frame.
878    #[tokio::test]
879    async fn test_deserialize_boolean() {
880        let bytes = Bytes::from_static(b"#t\r\n");
881
882        let frame = Frame::deserialize(bytes).await.unwrap();
883
884        assert_eq!(frame, Frame::Boolean(true));
885
886        let bytes = Bytes::from_static(b"#f\r\n");
887
888        let frame = Frame::deserialize(bytes).await.unwrap();
889
890        assert_eq!(frame, Frame::Boolean(false));
891    }
892
893    /// Tests the deserialization of a double frame.
894    #[tokio::test]
895    async fn test_deserialize_double() {
896        let bytes = Bytes::from_static(b",123.456\r\n");
897
898        let frame = Frame::deserialize(bytes).await.unwrap();
899
900        assert_eq!(frame, Frame::Double(123.456));
901
902        let bytes = Bytes::from_static(b",nan\r\n");
903
904        let frame = Frame::deserialize(bytes).await.unwrap();
905
906        if let Frame::Double(val) = frame {
907            assert!(val.is_nan());
908        } else {
909            panic!("Expected a Double frame");
910        }
911
912        let bytes = Bytes::from_static(b",inf\r\n");
913
914        let frame = Frame::deserialize(bytes).await.unwrap();
915
916        assert_eq!(frame, Frame::Double(f64::INFINITY));
917
918        let bytes = Bytes::from_static(b",-inf\r\n");
919
920        let frame = Frame::deserialize(bytes).await.unwrap();
921
922        assert_eq!(frame, Frame::Double(f64::NEG_INFINITY));
923    }
924
925    /// Tests the deserialization of a bulk error frame.
926    #[tokio::test]
927    async fn test_deserialize_bulk_error() {
928        let bytes = Bytes::from_static(b"!11\r\nHello Redis\r\n");
929
930        let frame = Frame::deserialize(bytes).await.unwrap();
931
932        assert_eq!(frame, Frame::BulkError(Bytes::from_static(b"Hello Redis")));
933
934        let bytes = Bytes::from_static(b"!0\r\n\r\n");
935
936        let frame = Frame::deserialize(bytes).await.unwrap();
937
938        assert_eq!(frame, Frame::BulkError(Bytes::from_static(b"")));
939    }
940
941    /// Tests the deserialization of a verbatim string frame.
942    #[tokio::test]
943    async fn test_deserialize_verbatim_string() {
944        let bytes = Bytes::from_static(b"=15\r\ntxt:Some string\r\n");
945
946        let frame = Frame::deserialize(bytes).await.unwrap();
947
948        assert_eq!(
949            frame,
950            Frame::VerbatimString(
951                Bytes::from_static(b"txt"),
952                Bytes::from_static(b"Some string")
953            )
954        );
955
956        let bytes = Bytes::from_static(b"=4\r\ntxt:\r\n");
957
958        let frame = Frame::deserialize(bytes).await.unwrap();
959
960        assert_eq!(
961            frame,
962            Frame::VerbatimString(Bytes::from_static(b"txt"), Bytes::from_static(b""))
963        );
964    }
965
966    /// Tests the deserialization of a map frame.
967    #[tokio::test]
968    async fn test_deserialize_map() {
969        let bytes = Bytes::from_static(b"%1\r\n+key\r\n+value\r\n");
970
971        let frame = Frame::deserialize(bytes).await.unwrap();
972
973        let mut expected_frame = Frame::Map(Vec::new());
974        expected_frame
975            .push_frame_to_map(
976                Frame::SimpleString("key".to_string()),
977                Frame::SimpleString("value".to_string()),
978            )
979            .unwrap();
980
981        assert_eq!(frame, expected_frame);
982    }
983
984    /// Tests the deserialization of a set frame.
985    #[tokio::test]
986    async fn test_deserialize_set() {
987        let bytes = Bytes::from_static(b"~2\r\n$5\r\nHello\r\n$5\r\nRedis\r\n");
988
989        let frame = Frame::deserialize(bytes).await.unwrap();
990
991        let mut expected_frame = Frame::Set(Vec::new());
992        expected_frame
993            .push_frame_to_array(Frame::BulkString(Bytes::from_static(b"Hello")))
994            .unwrap();
995        expected_frame
996            .push_frame_to_array(Frame::BulkString(Bytes::from_static(b"Redis")))
997            .unwrap();
998
999        assert_eq!(frame, expected_frame);
1000    }
1001}