@@ -17,7 +17,7 @@ use core::{borrow::Borrow, fmt, hash, ops, str};
17
17
18
18
use bytes:: Bytes ;
19
19
20
- /// An immutable UTF-8 encoded string with [`Bytes`] as a storage.
20
+ /// An immutable UTF-8 encoded string using [`Bytes`] as the storage.
21
21
#[ derive( Clone , Default , Eq , PartialOrd , Ord ) ]
22
22
pub struct ByteString ( Bytes ) ;
23
23
@@ -53,7 +53,29 @@ impl ByteString {
53
53
Self ( src)
54
54
}
55
55
56
- /// Returns a new byte string that is equivalent to the given `subset`.
56
+ /// Divides one bytestring into two at an index, returning both parts.
57
+ ///
58
+ /// # Panics
59
+ ///
60
+ /// Panics if `mid` is not on a UTF-8 code point boundary, or if it is past the end of the last
61
+ /// code point of the bytestring.
62
+ pub fn split_at ( & self , mid : usize ) -> ( ByteString , ByteString ) {
63
+ let this: & str = self . as_ref ( ) ;
64
+ let _valid_midpoint_check = this. split_at ( mid) ;
65
+
66
+ let mut bytes = self . 0 . clone ( ) ;
67
+ let first = bytes. split_to ( mid) ;
68
+ let last = bytes;
69
+
70
+ unsafe {
71
+ (
72
+ ByteString :: from_bytes_unchecked ( first) ,
73
+ ByteString :: from_bytes_unchecked ( last) ,
74
+ )
75
+ }
76
+ }
77
+
78
+ /// Returns a new `ByteString` that is equivalent to the given `subset`.
57
79
///
58
80
/// When processing a `ByteString` buffer with other tools, one often gets a `&str` which is in
59
81
/// fact a slice of the original `ByteString`; i.e., a subset of it. This function turns that
@@ -465,4 +487,33 @@ mod test {
465
487
// being a logical subset of the string
466
488
ByteString :: from_static ( "foo bar" ) . slice_ref ( "foo" ) ;
467
489
}
490
+
491
+ #[ test]
492
+ fn split_at ( ) {
493
+ let buf = ByteString :: from_static ( "foo bar" ) ;
494
+
495
+ let ( first, last) = buf. split_at ( 0 ) ;
496
+ assert_eq ! ( ByteString :: from_static( "" ) , first) ;
497
+ assert_eq ! ( ByteString :: from_static( "foo bar" ) , last) ;
498
+
499
+ let ( first, last) = buf. split_at ( 4 ) ;
500
+ assert_eq ! ( ByteString :: from_static( "foo " ) , first) ;
501
+ assert_eq ! ( ByteString :: from_static( "bar" ) , last) ;
502
+
503
+ let ( first, last) = buf. split_at ( 7 ) ;
504
+ assert_eq ! ( ByteString :: from_static( "foo bar" ) , first) ;
505
+ assert_eq ! ( ByteString :: from_static( "" ) , last) ;
506
+ }
507
+
508
+ #[ test]
509
+ #[ should_panic = "byte index 1 is not a char boundary;" ]
510
+ fn split_at_invalid_code_point ( ) {
511
+ ByteString :: from_static ( "µ" ) . split_at ( 1 ) ;
512
+ }
513
+
514
+ #[ test]
515
+ #[ should_panic = "byte index 9 is out of bounds" ]
516
+ fn split_at_outside_string ( ) {
517
+ ByteString :: from_static ( "foo" ) . split_at ( 9 ) ;
518
+ }
468
519
}
0 commit comments