@@ -76,9 +76,9 @@ pub enum Element {
7676 /// A response code
7777 RespCode ( RespCode ) ,
7878 /// An array of unicode strings
79- StrArray ( Vec < String > ) ,
79+ StrArray ( Vec < Option < String > > ) ,
8080 /// An array of binary strings
81- BinArray ( Vec < Vec < u8 > > ) ,
81+ BinArray ( Vec < Option < Vec < u8 > > > ) ,
8282}
8383
8484#[ derive( Debug , PartialEq ) ]
@@ -298,10 +298,49 @@ impl<'a> Parser<'a> {
298298 Err ( ParseError :: UnexpectedByte )
299299 }
300300 }
301+ /// Parse the next null checked element
302+ fn parse_next_chunk_nullck ( & mut self ) -> ParseResult < Option < & [ u8 ] > > {
303+ // we have the chunk
304+ let ( start, stop) = self . read_line ( ) ;
305+ if let Some ( sizeline) = self . buffer . get ( start..stop) {
306+ let string_size = Self :: parse_into_usize_nullck ( sizeline) ?;
307+ if let Some ( size) = string_size {
308+ // so it isn't null
309+ let our_chunk = self . read_until ( size) ?;
310+ Ok ( Some ( our_chunk) )
311+ } else {
312+ Ok ( None )
313+ }
314+ } else {
315+ Err ( ParseError :: NotEnough )
316+ }
317+ }
301318 /// The cursor should have passed the `+` tsymbol
302319 fn parse_next_string ( & mut self ) -> ParseResult < String > {
303320 Ok ( String :: from_utf8_lossy ( & self . parse_next_binstr ( ) ?) . to_string ( ) )
304321 }
322+ fn parse_next_binstr_nullck ( & mut self ) -> ParseResult < Option < Vec < u8 > > > {
323+ let our_chunk = self . parse_next_chunk_nullck ( ) ?;
324+ if let Some ( chunk) = our_chunk {
325+ let our_chunk = chunk. to_owned ( ) ;
326+ if self . will_cursor_give_linefeed ( ) ? {
327+ // there is a lf after the end of the binary string; great!
328+ // let's skip that now
329+ self . incr_cursor ( ) ;
330+ Ok ( Some ( our_chunk) )
331+ } else {
332+ Err ( ParseError :: UnexpectedByte )
333+ }
334+ } else {
335+ Ok ( None )
336+ }
337+ }
338+ fn parse_next_str_nullck ( & mut self ) -> ParseResult < Option < String > > {
339+ match self . parse_next_binstr_nullck ( ) ? {
340+ Some ( chunk) => Ok ( Some ( String :: from_utf8_lossy ( & chunk) . to_string ( ) ) ) ,
341+ None => Ok ( None ) ,
342+ }
343+ }
305344 /// The cursor should have passed the `:` tsymbol
306345 fn parse_next_u64 ( & mut self ) -> ParseResult < u64 > {
307346 let our_u64_chunk = self . __get_next_element ( ) ?;
@@ -362,31 +401,39 @@ impl<'a> Parser<'a> {
362401 Err ( ParseError :: NotEnough )
363402 }
364403 }
404+ /// Parse the next null checked usize
405+ fn parse_into_usize_nullck ( inp : & [ u8 ] ) -> ParseResult < Option < usize > > {
406+ if inp == [ 0 ] {
407+ Ok ( None )
408+ } else {
409+ Ok ( Some ( Self :: parse_into_usize ( inp) ?) )
410+ }
411+ }
365412 /// The cursor should have passed the `@+` chars
366- fn parse_next_typed_array_str ( & mut self ) -> ParseResult < Vec < String > > {
413+ fn parse_next_typed_array_str ( & mut self ) -> ParseResult < Vec < Option < String > > > {
367414 let ( start, stop) = self . read_line ( ) ;
368415 if let Some ( our_size_chunk) = self . buffer . get ( start..stop) {
369416 // so we have a size chunk; let's get the size
370417 let array_size = Self :: parse_into_usize ( our_size_chunk) ?;
371418 let mut array = Vec :: with_capacity ( array_size) ;
372419 for _ in 0 ..array_size {
373420 // no tsymbol, just elements and their sizes
374- array. push ( self . parse_next_string ( ) ?) ;
421+ array. push ( self . parse_next_str_nullck ( ) ?) ;
375422 }
376423 Ok ( array)
377424 } else {
378425 Err ( ParseError :: NotEnough )
379426 }
380427 }
381428 /// The cursor should have passed the `@?` chars
382- fn parse_next_typed_array_bin ( & mut self ) -> ParseResult < Vec < Vec < u8 > > > {
429+ fn parse_next_typed_array_bin ( & mut self ) -> ParseResult < Vec < Option < Vec < u8 > > > > {
383430 let ( start, stop) = self . read_line ( ) ;
384431 if let Some ( our_size_chunk) = self . buffer . get ( start..stop) {
385432 // got size chunk, let's get the size
386433 let array_size = Self :: parse_into_usize ( our_size_chunk) ?;
387434 let mut array = Vec :: with_capacity ( array_size) ;
388435 for _ in 0 ..array_size {
389- array. push ( self . parse_next_binstr ( ) ?) ;
436+ array. push ( self . parse_next_binstr_nullck ( ) ?) ;
390437 }
391438 Ok ( array)
392439 } else {
@@ -487,9 +534,9 @@ fn test_typed_str_array() {
487534 assert_eq ! (
488535 parsed,
489536 RawResponse :: SimpleQuery ( Element :: StrArray ( vec![
490- "the" . to_owned( ) ,
491- "cat" . to_owned( ) ,
492- "meowed" . to_owned( )
537+ Some ( "the" . to_owned( ) ) ,
538+ Some ( "cat" . to_owned( ) ) ,
539+ Some ( "meowed" . to_owned( ) )
493540 ] ) )
494541 ) ;
495542}
@@ -502,9 +549,39 @@ fn test_typed_bin_array() {
502549 assert_eq ! (
503550 parsed,
504551 RawResponse :: SimpleQuery ( Element :: BinArray ( vec![
505- Vec :: from( "the" ) ,
506- Vec :: from( "cat" ) ,
507- Vec :: from( "meowed" )
552+ Some ( Vec :: from( "the" ) ) ,
553+ Some ( Vec :: from( "cat" ) ) ,
554+ Some ( Vec :: from( "meowed" ) )
555+ ] ) )
556+ ) ;
557+ }
558+
559+ #[ test]
560+ fn test_typed_bin_array_null ( ) {
561+ let typed_array_packet = "*1\n @?3\n 3\n the\n 3\n cat\n \0 \n " . as_bytes ( ) ;
562+ let ( parsed, forward) = Parser :: new ( typed_array_packet) . parse ( ) . unwrap ( ) ;
563+ assert_eq ! ( forward, typed_array_packet. len( ) ) ;
564+ assert_eq ! (
565+ parsed,
566+ RawResponse :: SimpleQuery ( Element :: BinArray ( vec![
567+ Some ( Vec :: from( "the" ) ) ,
568+ Some ( Vec :: from( "cat" ) ) ,
569+ None
570+ ] ) )
571+ ) ;
572+ }
573+
574+ #[ test]
575+ fn test_typed_str_array_null ( ) {
576+ let typed_array_packet = "*1\n @+3\n 3\n the\n 3\n cat\n \0 \n " . as_bytes ( ) ;
577+ let ( parsed, forward) = Parser :: new ( typed_array_packet) . parse ( ) . unwrap ( ) ;
578+ assert_eq ! ( forward, typed_array_packet. len( ) ) ;
579+ assert_eq ! (
580+ parsed,
581+ RawResponse :: SimpleQuery ( Element :: StrArray ( vec![
582+ Some ( "the" . to_owned( ) ) ,
583+ Some ( "cat" . to_owned( ) ) ,
584+ None
508585 ] ) )
509586 ) ;
510587}
0 commit comments