@@ -333,6 +333,49 @@ impl<const N: usize> String<N> {
333
333
Some ( ch)
334
334
}
335
335
336
+ /// Removes a [`char`] from this `String` at a byte position and returns it.
337
+ ///
338
+ /// Note: Because this shifts over the remaining elements, it has a
339
+ /// worst-case performance of *O*(*n*).
340
+ ///
341
+ /// # Panics
342
+ ///
343
+ /// Panics if `idx` is larger than or equal to the `String`'s length,
344
+ /// or if it does not lie on a [`char`] boundary.
345
+ ///
346
+ /// # Examples
347
+ ///
348
+ /// Basic usage:
349
+ ///
350
+ /// ```
351
+ /// use heapless::String;
352
+ ///
353
+ /// let mut s: String<8> = String::from("foo");
354
+ ///
355
+ /// assert_eq!(s.remove(0), 'f');
356
+ /// assert_eq!(s.remove(1), 'o');
357
+ /// assert_eq!(s.remove(0), 'o');
358
+ /// ```
359
+ #[ inline]
360
+ pub fn remove ( & mut self , index : usize ) -> char {
361
+ let ch = match self [ index..] . chars ( ) . next ( ) {
362
+ Some ( ch) => ch,
363
+ None => panic ! ( "cannot remove a char from the end of a string" ) ,
364
+ } ;
365
+
366
+ let next = index + ch. len_utf8 ( ) ;
367
+ let len = self . len ( ) ;
368
+ unsafe {
369
+ core:: ptr:: copy (
370
+ self . vec . as_ptr ( ) . add ( next) ,
371
+ self . vec . as_mut_ptr ( ) . add ( index) ,
372
+ len - next,
373
+ ) ;
374
+ self . vec . set_len ( len - ( next - index) ) ;
375
+ }
376
+ ch
377
+ }
378
+
336
379
/// Truncates this `String`, removing all contents.
337
380
///
338
381
/// While this means the `String` will have a length of zero, it does not
@@ -796,4 +839,27 @@ mod tests {
796
839
assert_eq ! ( 0 , s. len( ) ) ;
797
840
assert_eq ! ( 8 , s. capacity( ) ) ;
798
841
}
842
+
843
+ #[ test]
844
+ fn remove ( ) {
845
+ let mut s: String < 8 > = String :: from ( "foo" ) ;
846
+ assert_eq ! ( s. remove( 0 ) , 'f' ) ;
847
+ assert_eq ! ( s. as_str( ) , "oo" ) ;
848
+ }
849
+
850
+ #[ test]
851
+ fn remove_uenc ( ) {
852
+ let mut s: String < 8 > = String :: from ( "ĝėēƶ" ) ;
853
+ assert_eq ! ( s. remove( 2 ) , 'ė' ) ;
854
+ assert_eq ! ( s. remove( 2 ) , 'ē' ) ;
855
+ assert_eq ! ( s. remove( 2 ) , 'ƶ' ) ;
856
+ assert_eq ! ( s. as_str( ) , "ĝ" ) ;
857
+ }
858
+
859
+ #[ test]
860
+ fn remove_uenc_combo_characters ( ) {
861
+ let mut s: String < 8 > = String :: from ( "héy" ) ;
862
+ assert_eq ! ( s. remove( 2 ) , '\u{0301}' ) ;
863
+ assert_eq ! ( s. as_str( ) , "hey" ) ;
864
+ }
799
865
}
0 commit comments