@@ -75,6 +75,10 @@ pub enum Element {
7575 FlatArray ( Vec < Vec < u8 > > ) ,
7676 /// A response code
7777 RespCode ( RespCode ) ,
78+ /// An array of unicode strings
79+ StrArray ( Vec < String > ) ,
80+ /// An array of binary strings
81+ BinArray ( Vec < Vec < u8 > > ) ,
7882}
7983
8084#[ derive( Debug , PartialEq ) ]
@@ -325,14 +329,30 @@ impl<'a> Parser<'a> {
325329 fn parse_next_element ( & mut self ) -> ParseResult < Element > {
326330 if let Some ( tsymbol) = self . buffer . get ( self . cursor ) {
327331 // so we have a tsymbol; nice, let's match it
328- // but advance the cursor before doing that
332+ // but advance the cursor before doing that (skip)
329333 self . incr_cursor ( ) ;
330334 let ret = match * tsymbol {
331335 b'?' => Element :: Binstr ( self . parse_next_binstr ( ) ?) ,
332336 b'+' => Element :: Str ( self . parse_next_string ( ) ?) ,
333337 b':' => Element :: UnsignedInt ( self . parse_next_u64 ( ) ?) ,
334338 b'&' => Element :: Array ( self . parse_next_array ( ) ?) ,
335339 b'!' => Element :: RespCode ( self . parse_next_respcode ( ) ?) ,
340+ b'@' => {
341+ // hmmm, a typed array; let's check the tsymbol
342+ if let Some ( array_type) = self . buffer . get ( self . cursor ) {
343+ // got tsymbol, let's skip it
344+ self . incr_cursor ( ) ;
345+ match array_type {
346+ b'+' => Element :: StrArray ( self . parse_next_typed_array_str ( ) ?) ,
347+ b'?' => Element :: BinArray ( self . parse_next_typed_array_bin ( ) ?) ,
348+ _ => return Err ( ParseError :: UnknownDatatype ) ,
349+ }
350+ } else {
351+ // if we couldn't fetch a tsymbol, there wasn't enough
352+ // data left
353+ return Err ( ParseError :: NotEnough ) ;
354+ }
355+ }
336356 b'_' => Element :: FlatArray ( self . parse_next_flat_array ( ) ?) ,
337357 _ => return Err ( ParseError :: UnknownDatatype ) ,
338358 } ;
@@ -342,6 +362,37 @@ impl<'a> Parser<'a> {
342362 Err ( ParseError :: NotEnough )
343363 }
344364 }
365+ /// The cursor should have passed the `@+` chars
366+ fn parse_next_typed_array_str ( & mut self ) -> ParseResult < Vec < String > > {
367+ let ( start, stop) = self . read_line ( ) ;
368+ if let Some ( our_size_chunk) = self . buffer . get ( start..stop) {
369+ // so we have a size chunk; let's get the size
370+ let array_size = Self :: parse_into_usize ( our_size_chunk) ?;
371+ let mut array = Vec :: with_capacity ( array_size) ;
372+ for _ in 0 ..array_size {
373+ // no tsymbol, just elements and their sizes
374+ array. push ( self . parse_next_string ( ) ?) ;
375+ }
376+ Ok ( array)
377+ } else {
378+ Err ( ParseError :: NotEnough )
379+ }
380+ }
381+ /// The cursor should have passed the `@?` chars
382+ fn parse_next_typed_array_bin ( & mut self ) -> ParseResult < Vec < Vec < u8 > > > {
383+ let ( start, stop) = self . read_line ( ) ;
384+ if let Some ( our_size_chunk) = self . buffer . get ( start..stop) {
385+ // got size chunk, let's get the size
386+ let array_size = Self :: parse_into_usize ( our_size_chunk) ?;
387+ let mut array = Vec :: with_capacity ( array_size) ;
388+ for _ in 0 ..array_size {
389+ array. push ( self . parse_next_binstr ( ) ?) ;
390+ }
391+ Ok ( array)
392+ } else {
393+ Err ( ParseError :: NotEnough )
394+ }
395+ }
345396 /// The cursor should have passed the tsymbol
346397 fn parse_next_flat_array ( & mut self ) -> ParseResult < Vec < Vec < u8 > > > {
347398 let ( start, stop) = self . read_line ( ) ;
@@ -427,3 +478,33 @@ impl<'a> Parser<'a> {
427478 }
428479 }
429480}
481+
482+ #[ test]
483+ fn test_typed_str_array ( ) {
484+ let typed_array_packet = "*1\n @+3\n 3\n the\n 3\n cat\n 6\n meowed\n " . as_bytes ( ) ;
485+ let ( parsed, forward) = Parser :: new ( typed_array_packet) . parse ( ) . unwrap ( ) ;
486+ assert_eq ! ( forward, typed_array_packet. len( ) ) ;
487+ assert_eq ! (
488+ parsed,
489+ RawResponse :: SimpleQuery ( Element :: StrArray ( vec![
490+ "the" . to_owned( ) ,
491+ "cat" . to_owned( ) ,
492+ "meowed" . to_owned( )
493+ ] ) )
494+ ) ;
495+ }
496+
497+ #[ test]
498+ fn test_typed_bin_array ( ) {
499+ let typed_array_packet = "*1\n @?3\n 3\n the\n 3\n cat\n 6\n meowed\n " . as_bytes ( ) ;
500+ let ( parsed, forward) = Parser :: new ( typed_array_packet) . parse ( ) . unwrap ( ) ;
501+ assert_eq ! ( forward, typed_array_packet. len( ) ) ;
502+ assert_eq ! (
503+ parsed,
504+ RawResponse :: SimpleQuery ( Element :: BinArray ( vec![
505+ Vec :: from( "the" ) ,
506+ Vec :: from( "cat" ) ,
507+ Vec :: from( "meowed" )
508+ ] ) )
509+ ) ;
510+ }
0 commit comments