11#[feature(" byte-span" )]
2- use crate :: byte_array :: {ByteSpanTrait , ToByteSpanTrait };
2+ use crate :: byte_array :: {ByteSpan , ByteSpanTrait , ToByteSpanTrait };
3+ use crate :: num :: traits :: Bounded ;
34use crate :: test :: test_utils :: {assert_eq, assert_ne};
45
56#[test]
@@ -508,39 +509,63 @@ fn test_from_collect() {
508509 assert_eq! (ba , " hello" );
509510}
510511
511- // TODO(giladchase): add dedicated is_empty test once we have `slice`.
512512#[test]
513513fn test_span_len () {
514- // Test simple happy flow --- value is included in the last word.
515514 // TODO(giladchase): add short string test here once supported cast into span.
516515 let ba : ByteArray = " A" ;
517516 let span = ba . span ();
518517 assert_eq! (span . len (), 1 );
519518 assert! (! span . is_empty ());
520519
520+ let ba_31 : ByteArray = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" ;
521+ let span = ba_31 . span ();
522+ assert_eq! (span . len (), 31 , " wrong span len" );
523+ assert! (! span . is_empty ());
524+
521525 // Test empty.
522526 let empty_ba : ByteArray = "" ;
523527 let empty_span = empty_ba . span ();
524528 assert_eq! (empty_span . len (), 0 );
525529 assert! (empty_span . is_empty ());
526530
527- // TODO(giladchase): Add start-offset using slice once supported.
528531 // First word in the array, second in last word.
529532 let two_byte31 : ByteArray = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg" ;
530- let mut single_span = two_byte31 . span ();
531- assert_eq! (single_span . len (), 33 , " len error with start offset" );
533+ let mut single_span = two_byte31 . span (). get ( 1 ..= 32 ) . unwrap () ;
534+ assert_eq! (single_span . len (), 32 , " len error with start offset" );
532535 assert! (! single_span . is_empty ());
533536
534- // TODO(giladchase): Add start-offset using slice once supported.
535537 // First word in the array, second in the array, third in last word.
536538 let three_bytes31 : ByteArray =
537539 " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#$" ; // 64 chars.
538- let mut three_span = three_bytes31 . span ();
539- assert_eq! (three_span . len (), 64 , " len error with size-3 bytearray" );
540+ let mut three_span = three_bytes31 . span (). get ( 1 .. 64 ) . unwrap () ;
541+ assert_eq! (three_span . len (), 63 , " len error with size-3 bytearray" );
540542 assert! (! three_span . is_empty ());
541543 // TODO(giladchase): use `ByteSpan::PartialEq` to check that a consuming slice == Default.
542544}
543545
546+ #[test]
547+ fn test_span_slice_is_empty () {
548+ let ba : ByteArray = " hello" ;
549+ let span = ba . span ();
550+
551+ let empty = span . get (2 .. 2 ). unwrap ();
552+ assert_eq! (empty . len (), 0 );
553+ assert! (empty . is_empty ());
554+ assert_eq! (empty . to_byte_array (), "" );
555+
556+ let ba_31 : ByteArray = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" ;
557+ let span = ba_31 . span ();
558+ assert! (span . get (30 .. 30 ). unwrap (). is_empty ());
559+ assert! (span . get (31 .. 31 ). unwrap (). is_empty ());
560+ assert! (! span . get (15 .. 30 ). unwrap (). is_empty ());
561+
562+ let ba_30 : ByteArray = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcd" ;
563+ let span = ba_30 . span ();
564+ assert! (span . get (29 .. 29 ). unwrap (). is_empty ());
565+ assert! (span . get (30 .. 30 ). unwrap (). is_empty ());
566+ assert! (! span . get (15 .. 29 ). unwrap (). is_empty ());
567+ }
568+
544569#[test]
545570fn test_span_copy () {
546571 let ba : ByteArray = " 12" ;
@@ -561,6 +586,85 @@ fn test_span_copy() {
561586 assert_eq! (ba , span . to_byte_array ());
562587}
563588
589+ #[test]
590+ fn test_span_slice_empty () {
591+ let ba : ByteArray = " hello" ;
592+ let span = ba . span ();
593+
594+ let empty = span . get (2 .. 2 ). unwrap ();
595+ assert_eq! (empty . len (), 0 );
596+ assert! (empty . is_empty ());
597+ assert_eq! (empty . to_byte_array (), "" );
598+ }
599+
600+ // TODO(giladchase): replace assert+is_none with assert_eq when we have PartialEq.
601+ #[test]
602+ fn test_span_slice_out_of_bounds () {
603+ let ba : ByteArray = " hello" ;
604+ let span = ba . span ();
605+
606+ assert! (span . get (3 ..= 7 ). is_none (), " end out of bounds" );
607+ assert! (span . get (6 ..= 6 ). is_none (), " start out of bounds (inclusive)" );
608+
609+ assert! (
610+ span . get (2 .. 4 ). unwrap (). get ((Bounded :: <usize >:: MAX - 1 ).. Bounded :: <usize >:: MAX ). is_none (),
611+ " start offset overflow" ,
612+ );
613+ assert! (
614+ span . get (2 ..= 3 ). unwrap (). get ((Bounded :: <usize >:: MAX - 1 ).. Bounded :: <usize >:: MAX ). is_none (),
615+ " start offset overflow (first get inclusive)" ,
616+ );
617+ assert! (
618+ span . get (2 .. 4 ). unwrap (). get ((Bounded :: <usize >:: MAX - 1 )..= Bounded :: <usize >:: MAX ). is_none (),
619+ " start offset overflow (second get inclusive)" ,
620+ );
621+ assert! (
622+ span . get (2 ..= 3 ). unwrap (). get ((Bounded :: <usize >:: MAX - 1 )..= Bounded :: <usize >:: MAX ). is_none (),
623+ " start offset overflow (both gets inclusive)" ,
624+ );
625+ assert! (span . get (Bounded :: <usize >:: MAX .. 0 ). is_none (), " backwards range" );
626+
627+ let empty_string : ByteArray = "" ;
628+ assert! (empty_string . span (). get (0 .. 2 ). is_none (), " empty slice is sliceable" );
629+ }
630+
631+ #[test]
632+ fn test_span_slice_under_31_bytes () {
633+ // Word entirely in remainder word.
634+ let ba : ByteArray = " abcde" ;
635+ let span = ba . span ();
636+ let tba = | ba : ByteSpan | ba . to_byte_array ();
637+
638+ assert_eq! (span . get (0 ..= 2 ). map (tba ), Some (" abc" ));
639+ assert_eq! (span . get (2 .. 4 ). map (tba ), Some (" cd" ));
640+ assert_eq! (span . get (4 ..= 4 ). map (tba ), Some (" e" ));
641+ }
642+ #[test]
643+ fn test_span_slice_exactly_31_bytes () {
644+ // 1 full data word, empty last_word.
645+ let ba_31 : ByteArray = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" ;
646+ let span = ba_31 . span ();
647+
648+ assert_eq! (span . len (), 31 );
649+ assert_eq! (span . get (0 .. 31 ). unwrap (). to_byte_array (), ba_31 );
650+ assert_eq! (span . get (10 ..= 19 ). unwrap (). to_byte_array (), " KLMNOPQRST" );
651+ }
652+
653+ #[test]
654+ fn test_span_slice_positions () {
655+ // Two full bytes31 + remainder with 2 bytes.
656+ let ba_64 : ByteArray = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#$" ;
657+ let span = ba_64 . span ();
658+ let tba = | ba : ByteSpan | ba . to_byte_array ();
659+
660+ assert_eq! (span . get (10 ..= 39 ). map (tba ), Some (" KLMNOPQRSTUVWXYZabcdefghijklmn" ));
661+ assert_eq! (
662+ span . get (5 .. 64 ). map (tba ),
663+ Some (" FGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#$" ),
664+ );
665+ assert_eq! (span . get (29 .. 49 ). map (tba ), Some (" defghijklmnopqrstuvw" ));
666+ }
667+
564668#[test]
565669fn test_span_to_bytearray () {
566670 let empty_ba : ByteArray = "" ;
@@ -578,5 +682,18 @@ fn test_span_to_bytearray() {
578682 let even_larger_ba : ByteArray =
579683 " abcdeFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#$" ; // 64 bytes
580684 assert_eq! (even_larger_ba . span (). to_byte_array (), even_larger_ba );
581- // TODO(giladchase): test with slice.
685+ }
686+
687+ #[test]
688+ fn test_span_multiple_start_offset_slicing () {
689+ let ba_6 : ByteArray = " abcdef" ;
690+ let span = ba_6 . span ();
691+
692+ let slice1_inc = span . get (1 ..= 5 ). unwrap ();
693+ let slice2_inc = slice1_inc . get (1 ..= 4 ). unwrap ();
694+ let slice3_inc = slice2_inc . get (1 ..= 3 ). unwrap ();
695+
696+ assert_eq! (slice1_inc . to_byte_array (), " bcdef" );
697+ assert_eq! (slice2_inc . to_byte_array (), " cdef" );
698+ assert_eq! (slice3_inc . to_byte_array (), " def" );
582699}
0 commit comments