@@ -9,7 +9,8 @@ use core::str::from_utf8;
9
9
use core:: { cmp:: min, ops:: * } ;
10
10
#[ cfg( feature = "logs" ) ]
11
11
use log:: { debug, trace} ;
12
- use std:: usize;
12
+ use no_panic:: no_panic;
13
+ use std:: { ptr, usize} ;
13
14
14
15
/// String based on a generic array (size defined at compile time through `const generics`)
15
16
///
@@ -470,15 +471,21 @@ where
470
471
/// # }
471
472
/// ```
472
473
#[ inline]
474
+ #[ cfg_attr( not( debug_assertions) , no_panic) ]
473
475
pub fn try_push_str ( & mut self , string : impl AsRef < str > ) -> Result < ( ) , OutOfBounds > {
474
476
trace ! ( "Push str: {}" , string. as_ref( ) ) ;
475
477
let str = string. as_ref ( ) . as_bytes ( ) ;
476
478
if str. len ( ) == 0 {
477
479
return Ok ( ( ) ) ;
478
480
}
479
481
is_inside_boundary ( str. len ( ) + self . len ( ) , Self :: capacity ( ) ) ?;
480
- let this_len = self . len ( ) ;
481
- self . array [ this_len..this_len + str. len ( ) ] . copy_from_slice ( str) ;
482
+ unsafe {
483
+ ptr:: copy_nonoverlapping (
484
+ str. as_ptr ( ) ,
485
+ self . array . as_mut_ptr ( ) . add ( self . len ( ) ) ,
486
+ str. len ( ) ,
487
+ ) ;
488
+ }
482
489
self . size += str. len ( ) as u8 ;
483
490
return Ok ( ( ) ) ;
484
491
}
@@ -502,17 +509,22 @@ where
502
509
/// # }
503
510
/// ```
504
511
#[ inline]
512
+ #[ cfg_attr( not( debug_assertions) , no_panic) ]
505
513
pub fn push_str_truncate ( & mut self , string : impl AsRef < str > ) {
506
514
trace ! ( "Push str truncate: {}" , string. as_ref( ) ) ;
515
+ let str = string. as_ref ( ) . as_bytes ( ) ;
507
516
let size = Self :: capacity ( ) - self . len ( ) ;
508
- if size == 0 {
517
+ if size == 0 || str . len ( ) == 0 {
509
518
return ;
510
519
}
511
- let str = truncate_str ( string. as_ref ( ) . as_bytes ( ) , size. into ( ) ) ;
512
- if str. len ( ) == 0 {
513
- return ;
520
+ let str = truncate_str ( str, size) ;
521
+ unsafe {
522
+ ptr:: copy_nonoverlapping (
523
+ str. as_ptr ( ) ,
524
+ self . array . as_mut_ptr ( ) . add ( self . len ( ) ) ,
525
+ str. len ( ) ,
526
+ ) ;
514
527
}
515
- self . array [ self . size as usize ..self . size as usize + str. len ( ) ] . copy_from_slice ( str) ;
516
528
self . size += str. len ( ) as u8 ;
517
529
}
518
530
@@ -983,15 +995,6 @@ where
983
995
Bound :: Excluded ( t) => * t,
984
996
Bound :: Unbounded => self . len ( ) ,
985
997
} ;
986
- is_inside_boundary ( start, end) ?;
987
- is_inside_boundary ( end, self . len ( ) ) ?;
988
- is_char_boundary ( self , start) ?;
989
- is_char_boundary ( self , end) ?;
990
- let r_len = end - start;
991
- is_inside_boundary ( start + str. len ( ) + self . len ( ) - end, Self :: capacity ( ) ) ?;
992
- if start == end && with. as_ref ( ) . len ( ) == 0 {
993
- return Ok ( ( ) ) ;
994
- }
995
998
debug ! (
996
999
"Replace range (len: {}) ({}..{}) with (len: {}) {}" ,
997
1000
self . len( ) ,
@@ -1000,13 +1003,21 @@ where
1000
1003
with. as_ref( ) . len( ) ,
1001
1004
with. as_ref( )
1002
1005
) ;
1006
+ if start == end && str. len ( ) == 0 {
1007
+ return Ok ( ( ) ) ;
1008
+ }
1009
+ is_inside_boundary ( start, end) ?;
1010
+ is_inside_boundary ( end, self . len ( ) ) ?;
1011
+ is_char_boundary ( self , start) ?;
1012
+ is_char_boundary ( self , end) ?;
1013
+ is_inside_boundary ( start + str. len ( ) + self . len ( ) - end, Self :: capacity ( ) ) ?;
1003
1014
let dest = start + str. len ( ) ;
1004
1015
let this_len = self . len ( ) ;
1005
1016
self . array . copy_within ( end..this_len, dest) ;
1006
1017
if str. len ( ) > 0 {
1007
1018
self . array [ start..start + str. len ( ) ] . copy_from_slice ( str) ;
1008
1019
}
1009
- self . size -= r_len as u8 ;
1020
+ self . size -= ( end - start ) as u8 ;
1010
1021
self . size += str. len ( ) as u8 ;
1011
1022
Ok ( ( ) )
1012
1023
}
0 commit comments