@@ -20,18 +20,18 @@ use core::ops::{self, Range, RangeBounds};
2020use core:: ops:: { Add , AddAssign } ;
2121use core:: ptr;
2222use core:: slice;
23- use core:: str:: pattern:: Pattern ;
23+ use core:: str:: pattern:: { Pattern , Utf8Pattern } ;
2424
2525use crate :: alloc:: { Allocator , Global } ;
2626#[ cfg( not( no_global_oom_handling) ) ]
2727use crate :: borrow:: { Cow , ToOwned } ;
2828use crate :: boxed:: Box ;
2929use crate :: collections:: TryReserveError ;
30- use crate :: str:: { self , from_utf8_unchecked_mut, Chars , Utf8Error } ;
30+ use crate :: str:: { self , from_utf8_unchecked_mut, CharIndices , Chars , Utf8Error } ;
3131#[ cfg( not( no_global_oom_handling) ) ]
3232use crate :: str:: { from_boxed_utf8_unchecked, FromStr } ;
3333use crate :: string:: ToString ;
34- use crate :: vec:: Vec ;
34+ use crate :: vec:: { self , Vec } ;
3535
3636/// A UTF-8–encoded, growable string, with allocator support.
3737///
@@ -491,6 +491,37 @@ impl<A: Allocator> String<A> {
491491 pub fn allocator ( & self ) -> & A {
492492 self . vec . allocator ( )
493493 }
494+
495+ fn from_utf8_lossy_in ( v : & [ u8 ] , alloc : A ) -> Result < & str , String < A > > {
496+ let mut iter = v. utf8_chunks ( ) ;
497+
498+ let first_valid = if let Some ( chunk) = iter. next ( ) {
499+ let valid = chunk. valid ( ) ;
500+ if chunk. invalid ( ) . is_empty ( ) {
501+ debug_assert_eq ! ( valid. len( ) , v. len( ) ) ;
502+ return Ok ( valid) ;
503+ }
504+ valid
505+ } else {
506+ return Ok ( "" ) ;
507+ } ;
508+
509+ const REPLACEMENT : & str = "\u{FFFD} " ;
510+
511+ let mut res = String :: with_capacity_in ( v. len ( ) , alloc) ;
512+ res. push_str ( first_valid) ;
513+ res. push_str ( REPLACEMENT ) ;
514+
515+ for chunk in iter {
516+ res. push_str ( chunk. valid ( ) ) ;
517+ if !chunk. invalid ( ) . is_empty ( ) {
518+ res. push_str ( REPLACEMENT ) ;
519+ }
520+ }
521+
522+ Err ( res)
523+ }
524+
494525}
495526
496527impl String {
@@ -547,42 +578,12 @@ impl String {
547578 #[ cfg( not( no_global_oom_handling) ) ]
548579 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
549580 pub fn from_utf8_lossy ( v : & [ u8 ] ) -> Cow < ' _ , str > {
550- match String :: from_utf8_lossy_in ( Global ) {
581+ match String :: from_utf8_lossy_in ( v , Global ) {
551582 Ok ( s) => Cow :: Borrowed ( s) ,
552583 Err ( s) => Cow :: Owned ( s) ,
553584 }
554585 }
555586
556- fn from_utf8_lossy_in ( v : & [ u8 ] , alloc : A ) -> Result < & str , String < A > > {
557- let mut iter = v. utf8_chunks ( ) ;
558-
559- let first_valid = if let Some ( chunk) = iter. next ( ) {
560- let valid = chunk. valid ( ) ;
561- if chunk. invalid ( ) . is_empty ( ) {
562- debug_assert_eq ! ( valid. len( ) , v. len( ) ) ;
563- return Ok ( valid) ;
564- }
565- valid
566- } else {
567- return Ok ( "" ) ;
568- } ;
569-
570- const REPLACEMENT : & str = "\u{FFFD} " ;
571-
572- let mut res = String :: with_capacity_in ( v. len ( ) , alloc) ;
573- res. push_str ( first_valid) ;
574- res. push_str ( REPLACEMENT ) ;
575-
576- for chunk in iter {
577- res. push_str ( chunk. valid ( ) ) ;
578- if !chunk. invalid ( ) . is_empty ( ) {
579- res. push_str ( REPLACEMENT ) ;
580- }
581- }
582-
583- Err ( res)
584- }
585-
586587 /// Converts a [`Vec<u8>`] to a `String`, substituting invalid UTF-8
587588 /// sequences with replacement characters.
588589 ///
0 commit comments