@@ -594,6 +594,41 @@ where
594
594
}
595
595
}
596
596
597
+ /// Like `from_utf8_lossy`, but this honors COOP_PREFERRED.
598
+ #[ unstable( feature = "compile_check_struct_with_const_generic_added_associated_function" , reason = "confirm_or_fix_the_function_name" , issue = "none" ) ]
599
+ pub fn from_utf8_lossy_coop_or_not ( v : & [ u8 ] ) -> Cow < ' _ , str , COOP_PREFERRED > {
600
+ let mut iter = Utf8Chunks :: new ( v) ;
601
+
602
+ let first_valid = if let Some ( chunk) = iter. next ( ) {
603
+ let valid = chunk. valid ( ) ;
604
+ if chunk. invalid ( ) . is_empty ( ) {
605
+ debug_assert_eq ! ( valid. len( ) , v. len( ) ) ;
606
+ return Cow :: Borrowed ( valid) ;
607
+ }
608
+ valid
609
+ } else {
610
+ return Cow :: Borrowed ( "" ) ;
611
+ } ;
612
+
613
+ const REPLACEMENT : & str = "\u{FFFD} " ;
614
+
615
+ #[ allow( unused_braces) ]
616
+ let mut res = String :: < COOP_PREFERRED > :: with_capacity ( v. len ( ) ) ;
617
+ res. push_str ( first_valid) ;
618
+ res. push_str ( REPLACEMENT ) ;
619
+
620
+ for chunk in iter {
621
+ res. push_str ( chunk. valid ( ) ) ;
622
+ if !chunk. invalid ( ) . is_empty ( ) {
623
+ res. push_str ( REPLACEMENT ) ;
624
+ }
625
+ }
626
+
627
+ Cow :: Owned ( res)
628
+ }
629
+ }
630
+
631
+ impl String {
597
632
/// Converts a slice of bytes to a string, including invalid characters.
598
633
///
599
634
/// Strings are made of bytes ([`u8`]), and a slice of bytes
@@ -643,39 +678,22 @@ where
643
678
///
644
679
/// assert_eq!("Hello �World", output);
645
680
/// ```
681
+ /// @FIXME Should this return Cow<'_, str, false> instead, so it's both
682
+ /// - backwards compatible, and
683
+ /// - independent of DEFAULT_COOP_PREFERRED (for backwards compatbility)? But `String` (and others) use default, too.
646
684
#[ must_use]
647
685
#[ cfg( not( no_global_oom_handling) ) ]
648
686
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
649
- pub fn from_utf8_lossy ( v : & [ u8 ] ) -> Cow < ' _ , str , COOP_PREFERRED > {
650
- let mut iter = Utf8Chunks :: new ( v) ;
651
-
652
- let first_valid = if let Some ( chunk) = iter. next ( ) {
653
- let valid = chunk. valid ( ) ;
654
- if chunk. invalid ( ) . is_empty ( ) {
655
- debug_assert_eq ! ( valid. len( ) , v. len( ) ) ;
656
- return Cow :: Borrowed ( valid) ;
657
- }
658
- valid
659
- } else {
660
- return Cow :: Borrowed ( "" ) ;
661
- } ;
662
-
663
- const REPLACEMENT : & str = "\u{FFFD} " ;
664
-
665
- let mut res = String :: < COOP_PREFERRED > :: with_capacity ( v. len ( ) ) ;
666
- res. push_str ( first_valid) ;
667
- res. push_str ( REPLACEMENT ) ;
668
-
669
- for chunk in iter {
670
- res. push_str ( chunk. valid ( ) ) ;
671
- if !chunk. invalid ( ) . is_empty ( ) {
672
- res. push_str ( REPLACEMENT ) ;
673
- }
674
- }
675
-
676
- Cow :: Owned ( res)
687
+ #[ allow( unused_braces) ]
688
+ pub fn from_utf8_lossy ( v : & [ u8 ] ) -> Cow < ' _ , str , { DEFAULT_COOP_PREFERRED ! ( ) } > {
689
+ String :: < { DEFAULT_COOP_PREFERRED ! ( ) } > :: from_utf8_lossy_coop_or_not ( v)
677
690
}
691
+ }
678
692
693
+ impl < const COOP_PREFERRED : bool > String < COOP_PREFERRED >
694
+ where
695
+ [ ( ) ; core:: alloc:: co_alloc_metadata_num_slots_with_preference :: < Global > ( COOP_PREFERRED ) ] : ,
696
+ {
679
697
/// Decode a UTF-16–encoded vector `v` into a `String`, returning [`Err`]
680
698
/// if `v` contains any invalid data.
681
699
///
0 commit comments