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,58 @@ 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" ;
517- let span = ba . span ();
518- assert_eq! (span . len (), 1 );
519- assert! (! span . is_empty ());
516+ assert_eq! (ba . span (). len (), 1 );
517+ assert! (! ba . span (). is_empty ());
518+
519+ let ba_31 : ByteArray = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" ;
520+ assert_eq! (ba_31 . span (). len (), 31 );
521+ assert! (! ba_31 . span (). is_empty ());
520522
521- // Test empty.
522523 let empty_ba : ByteArray = "" ;
523- let empty_span = empty_ba . span ();
524- assert_eq! (empty_span . len (), 0 );
525- assert! (empty_span . is_empty ());
524+ assert_eq! (empty_ba . span (). len (), 0 );
525+ assert! (empty_ba . span (). is_empty ());
526526
527- // TODO(giladchase): Add start-offset using slice once supported.
528527 // First word in the array, second in last word.
529528 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" );
532- assert! ( ! single_span . is_empty ());
529+ let single_span = two_byte31 . span () . get ( 1 ..= 32 );
530+ assert_eq! (single_span . map ( | s | s . len ()), Some ( 32 ) , " len error with start offset" );
531+ assert_eq! ( single_span . map ( | s | s . is_empty ()), Some ( false ));
533532
534- // TODO(giladchase): Add start-offset using slice once supported.
535- // First word in the array, second in the array, third in last word.
533+ // First word in the array, second in the array, third in remainder.
536534 let three_bytes31 : ByteArray =
537535 " 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- assert! ( ! three_span . is_empty ());
536+ let three_span = three_bytes31 . span () . get ( 1 .. 64 );
537+ assert_eq! (three_span . map ( | s | s . len ()), Some ( 63 ) , " len error with size-3 bytearray" );
538+ assert_eq! ( three_span . map ( | s | s . is_empty ()), Some ( false ));
541539 // TODO(giladchase): use `ByteSpan::PartialEq` to check that a consuming slice == Default.
542540}
543541
542+ #[test]
543+ fn test_span_slice_is_empty () {
544+ let ba : ByteArray = " hello" ;
545+ let span = ba . span ();
546+ let is_empty = | span : ByteSpan | span . is_empty ();
547+
548+ let empty = span . get (2 .. 2 );
549+ assert_eq! (empty . map (| s | s . len ()), Some (0 ));
550+ assert_eq! (empty . map (is_empty ), Some (true ));
551+ assert_eq! (empty . map (| s | s . to_byte_array ()), Some ("" ));
552+
553+ let ba_31 : ByteArray = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" ;
554+ assert_eq! (ba_31 . span (). get (30 .. 30 ). map (is_empty ), Some (true ));
555+ assert_eq! (ba_31 . span (). get (31 .. 31 ). map (is_empty ), Some (true ));
556+ assert_eq! (ba_31 . span (). get (15 .. 30 ). map (is_empty ), Some (false ));
557+
558+ let ba_30 : ByteArray = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcd" ;
559+ assert_eq! (ba_30 . span (). get (29 .. 29 ). map (is_empty ), Some (true ));
560+ assert_eq! (ba_30 . span (). get (30 .. 30 ). map (is_empty ), Some (true ));
561+ assert_eq! (ba_30 . span (). get (15 .. 29 ). map (is_empty ), Some (false ));
562+ }
563+
544564#[test]
545565fn test_span_copy () {
546566 let ba : ByteArray = " 12" ;
@@ -561,6 +581,85 @@ fn test_span_copy() {
561581 assert_eq! (ba , span . to_byte_array ());
562582}
563583
584+ #[test]
585+ fn test_span_slice_empty () {
586+ let ba : ByteArray = " hello" ;
587+ let span = ba . span ();
588+
589+ let empty = span . get (2 .. 2 ). unwrap ();
590+ assert_eq! (empty . len (), 0 );
591+ assert! (empty . is_empty ());
592+ assert_eq! (empty . to_byte_array (), "" );
593+ }
594+
595+ // TODO(giladchase): replace assert+is_none with assert_eq when we have PartialEq.
596+ #[test]
597+ fn test_span_slice_out_of_bounds () {
598+ let ba : ByteArray = " hello" ;
599+ let span = ba . span ();
600+
601+ assert! (span . get (3 ..= 7 ). is_none (), " end out of bounds" );
602+ assert! (span . get (6 ..= 6 ). is_none (), " start out of bounds (inclusive)" );
603+
604+ assert! (
605+ span . get (2 .. 4 ). unwrap (). get ((Bounded :: <usize >:: MAX - 1 ).. Bounded :: <usize >:: MAX ). is_none (),
606+ " start offset overflow" ,
607+ );
608+ assert! (
609+ span . get (2 ..= 3 ). unwrap (). get ((Bounded :: <usize >:: MAX - 1 ).. Bounded :: <usize >:: MAX ). is_none (),
610+ " start offset overflow (first get inclusive)" ,
611+ );
612+ assert! (
613+ span . get (2 .. 4 ). unwrap (). get ((Bounded :: <usize >:: MAX - 1 )..= Bounded :: <usize >:: MAX ). is_none (),
614+ " start offset overflow (second get inclusive)" ,
615+ );
616+ assert! (
617+ span . get (2 ..= 3 ). unwrap (). get ((Bounded :: <usize >:: MAX - 1 )..= Bounded :: <usize >:: MAX ). is_none (),
618+ " start offset overflow (both gets inclusive)" ,
619+ );
620+ assert! (span . get (Bounded :: <usize >:: MAX .. 0 ). is_none (), " backwards range" );
621+
622+ let empty_string : ByteArray = "" ;
623+ assert! (empty_string . span (). get (0 .. 2 ). is_none (), " empty slice is sliceable" );
624+ }
625+
626+ #[test]
627+ fn test_span_slice_under_31_bytes () {
628+ // Word entirely in remainder word.
629+ let ba : ByteArray = " abcde" ;
630+ let span = ba . span ();
631+ let tba = | ba : ByteSpan | ba . to_byte_array ();
632+
633+ assert_eq! (span . get (0 ..= 2 ). map (tba ), Some (" abc" ));
634+ assert_eq! (span . get (2 .. 4 ). map (tba ), Some (" cd" ));
635+ assert_eq! (span . get (4 ..= 4 ). map (tba ), Some (" e" ));
636+ }
637+ #[test]
638+ fn test_span_slice_exactly_31_bytes () {
639+ // 1 full data word, empty last_word.
640+ let ba_31 : ByteArray = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" ;
641+ let span = ba_31 . span ();
642+
643+ assert_eq! (span . len (), 31 );
644+ assert_eq! (span . get (0 .. 31 ). unwrap (). to_byte_array (), ba_31 );
645+ assert_eq! (span . get (10 ..= 19 ). unwrap (). to_byte_array (), " KLMNOPQRST" );
646+ }
647+
648+ #[test]
649+ fn test_span_slice_positions () {
650+ // Two full bytes31 + remainder with 2 bytes.
651+ let ba_64 : ByteArray = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#$" ;
652+ let span = ba_64 . span ();
653+ let tba = | ba : ByteSpan | ba . to_byte_array ();
654+
655+ assert_eq! (span . get (10 ..= 39 ). map (tba ), Some (" KLMNOPQRSTUVWXYZabcdefghijklmn" ));
656+ assert_eq! (
657+ span . get (5 .. 64 ). map (tba ),
658+ Some (" FGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#$" ),
659+ );
660+ assert_eq! (span . get (29 .. 49 ). map (tba ), Some (" defghijklmnopqrstuvw" ));
661+ }
662+
564663#[test]
565664fn test_span_to_bytearray () {
566665 let empty_ba : ByteArray = "" ;
@@ -578,5 +677,18 @@ fn test_span_to_bytearray() {
578677 let even_larger_ba : ByteArray =
579678 " abcdeFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#$" ; // 64 bytes
580679 assert_eq! (even_larger_ba . span (). to_byte_array (), even_larger_ba );
581- // TODO(giladchase): test with slice.
680+ }
681+
682+ #[test]
683+ fn test_span_multiple_start_offset_slicing () {
684+ let ba_6 : ByteArray = " abcdef" ;
685+ let span = ba_6 . span ();
686+
687+ let slice1_inc = span . get (1 ..= 5 ). unwrap ();
688+ let slice2_inc = slice1_inc . get (1 ..= 4 ). unwrap ();
689+ let slice3_inc = slice2_inc . get (1 ..= 3 ). unwrap ();
690+
691+ assert_eq! (slice1_inc . to_byte_array (), " bcdef" );
692+ assert_eq! (slice2_inc . to_byte_array (), " cdef" );
693+ assert_eq! (slice3_inc . to_byte_array (), " def" );
582694}
0 commit comments