@@ -662,6 +662,56 @@ impl String {
662
662
Cow :: Owned ( res)
663
663
}
664
664
665
+ /// Converts a [`Vec<u8>`] to a `String`, substituting invalid UTF-8
666
+ /// sequences with replacement characters.
667
+ ///
668
+ /// See [`from_utf8_lossy`] for more details.
669
+ ///
670
+ /// [`from_utf8_lossy`]: String::from_utf8_lossy
671
+ ///
672
+ /// Note that this function does not guarantee reuse of the original `Vec`
673
+ /// allocation.
674
+ ///
675
+ /// # Examples
676
+ ///
677
+ /// Basic usage:
678
+ ///
679
+ /// ```
680
+ /// #![feature(string_from_utf8_lossy_owned)]
681
+ /// // some bytes, in a vector
682
+ /// let sparkle_heart = vec![240, 159, 146, 150];
683
+ ///
684
+ /// let sparkle_heart = String::from_utf8_lossy_owned(sparkle_heart);
685
+ ///
686
+ /// assert_eq!(String::from("💖"), sparkle_heart);
687
+ /// ```
688
+ ///
689
+ /// Incorrect bytes:
690
+ ///
691
+ /// ```
692
+ /// #![feature(string_from_utf8_lossy_owned)]
693
+ /// // some invalid bytes
694
+ /// let input: Vec<u8> = b"Hello \xF0\x90\x80World".into();
695
+ /// let output = String::from_utf8_lossy_owned(input);
696
+ ///
697
+ /// assert_eq!(String::from("Hello �World"), output);
698
+ /// ```
699
+ #[ must_use]
700
+ #[ cfg( not( no_global_oom_handling) ) ]
701
+ #[ unstable( feature = "string_from_utf8_lossy_owned" , issue = "129436" ) ]
702
+ pub fn from_utf8_lossy_owned ( v : Vec < u8 > ) -> String {
703
+ if let Cow :: Owned ( string) = String :: from_utf8_lossy ( & v) {
704
+ string
705
+ } else {
706
+ // SAFETY: `String::from_utf8_lossy`'s contract ensures that if
707
+ // it returns a `Cow::Borrowed`, it is a valid UTF-8 string.
708
+ // Otherwise, it returns a new allocation of an owned `String`, with
709
+ // replacement characters for invalid sequences, which is returned
710
+ // above.
711
+ unsafe { String :: from_utf8_unchecked ( v) }
712
+ }
713
+ }
714
+
665
715
/// Decode a UTF-16–encoded vector `v` into a `String`, returning [`Err`]
666
716
/// if `v` contains any invalid data.
667
717
///
@@ -2012,6 +2062,30 @@ impl FromUtf8Error {
2012
2062
& self . bytes [ ..]
2013
2063
}
2014
2064
2065
+ /// Converts the bytes into a `String` lossily, substituting invalid UTF-8
2066
+ /// sequences with replacement characters.
2067
+ ///
2068
+ /// See [`String::from_utf8_lossy`] for more details on replacement of
2069
+ /// invalid sequences, and [`String::from_utf8_lossy_owned`] for the
2070
+ /// `String` function which corresponds to this function.
2071
+ ///
2072
+ /// # Examples
2073
+ ///
2074
+ /// ```
2075
+ /// #![feature(string_from_utf8_lossy_owned)]
2076
+ /// // some invalid bytes
2077
+ /// let input: Vec<u8> = b"Hello \xF0\x90\x80World".into();
2078
+ /// let output = String::from_utf8(input).unwrap_or_else(|e| e.into_utf8_lossy());
2079
+ ///
2080
+ /// assert_eq!(String::from("Hello �World"), output);
2081
+ /// ```
2082
+ #[ must_use]
2083
+ #[ cfg( not( no_global_oom_handling) ) ]
2084
+ #[ unstable( feature = "string_from_utf8_lossy_owned" , issue = "129436" ) ]
2085
+ pub fn into_utf8_lossy ( self ) -> String {
2086
+ String :: from_utf8_lossy_owned ( self . bytes )
2087
+ }
2088
+
2015
2089
/// Returns the bytes that were attempted to convert to a `String`.
2016
2090
///
2017
2091
/// This method is carefully constructed to avoid allocation. It will
0 commit comments