@@ -62,7 +62,7 @@ use crate::alloc::Allocator;
6262use crate :: borrow:: { Cow , ToOwned } ;
6363use crate :: boxed:: Box ;
6464use crate :: collections:: TryReserveError ;
65- use crate :: str:: { self , Chars , Utf8Error , from_utf8_unchecked_mut} ;
65+ use crate :: str:: { self , CharIndices , Chars , Utf8Error , from_utf8_unchecked_mut} ;
6666#[ cfg( not( no_global_oom_handling) ) ]
6767use crate :: str:: { FromStr , from_boxed_utf8_unchecked} ;
6868use crate :: vec:: Vec ;
@@ -1952,6 +1952,12 @@ impl String {
19521952 Drain { start, end, iter : chars_iter, string : self_ptr }
19531953 }
19541954
1955+ /// Placeholder docs.
1956+ #[ unstable( feature = "into_chars" , reason = "new API" , issue = "none" ) ]
1957+ pub fn into_chars ( self ) -> IntoChars {
1958+ IntoChars { bytes : self . into_bytes ( ) }
1959+ }
1960+
19551961 /// Removes the specified range in the string,
19561962 /// and replaces it with the given string.
19571963 /// The given string doesn't need to be the same length as the range.
@@ -3094,6 +3100,91 @@ impl fmt::Write for String {
30943100 }
30953101}
30963102
3103+ /// Placeholder docs.
3104+ #[ unstable( feature = "into_chars" , reason = "new API" , issue = "none" ) ]
3105+ pub struct IntoChars {
3106+ bytes : Vec < u8 > ,
3107+ }
3108+
3109+ #[ unstable( feature = "into_chars" , reason = "new API" , issue = "none" ) ]
3110+ impl fmt:: Debug for IntoChars {
3111+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
3112+ f. debug_tuple ( "IntoChars" ) . field ( & self . as_str ( ) ) . finish ( )
3113+ }
3114+ }
3115+
3116+ #[ unstable( feature = "into_chars" , reason = "new API" , issue = "none" ) ]
3117+ impl IntoChars {
3118+ /// Placeholder docs.
3119+ pub fn as_str ( & self ) -> & str {
3120+ // SAFETY: `bytes` is a valid UTF-8 string.
3121+ unsafe { str:: from_utf8_unchecked ( self . bytes . as_slice ( ) ) }
3122+ }
3123+
3124+ fn iter ( & self ) -> CharIndices < ' _ > {
3125+ self . as_str ( ) . char_indices ( )
3126+ }
3127+ }
3128+
3129+ #[ unstable( feature = "into_chars" , reason = "new API" , issue = "none" ) ]
3130+ impl AsRef < str > for IntoChars {
3131+ fn as_ref ( & self ) -> & str {
3132+ self . as_str ( )
3133+ }
3134+ }
3135+
3136+ #[ unstable( feature = "into_chars" , reason = "new API" , issue = "none" ) ]
3137+ impl AsRef < [ u8 ] > for IntoChars {
3138+ fn as_ref ( & self ) -> & [ u8 ] {
3139+ self . bytes . as_slice ( )
3140+ }
3141+ }
3142+
3143+ #[ unstable( feature = "into_chars" , reason = "new API" , issue = "none" ) ]
3144+ impl Iterator for IntoChars {
3145+ type Item = char ;
3146+
3147+ #[ inline]
3148+ fn next ( & mut self ) -> Option < char > {
3149+ let mut iter = self . iter ( ) ;
3150+ match iter. next ( ) {
3151+ None => None ,
3152+ Some ( ( _, ch) ) => {
3153+ let offset = iter. offset ( ) ;
3154+ drop ( self . bytes . drain ( ..offset) ) ;
3155+ Some ( ch)
3156+ }
3157+ }
3158+ }
3159+
3160+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
3161+ self . iter ( ) . size_hint ( )
3162+ }
3163+
3164+ #[ inline]
3165+ fn last ( mut self ) -> Option < char > {
3166+ self . next_back ( )
3167+ }
3168+ }
3169+
3170+ #[ unstable( feature = "into_chars" , reason = "new API" , issue = "none" ) ]
3171+ impl DoubleEndedIterator for IntoChars {
3172+ #[ inline]
3173+ fn next_back ( & mut self ) -> Option < char > {
3174+ let mut iter = self . iter ( ) ;
3175+ match iter. next_back ( ) {
3176+ None => None ,
3177+ Some ( ( idx, ch) ) => {
3178+ self . bytes . truncate ( idx) ;
3179+ Some ( ch)
3180+ }
3181+ }
3182+ }
3183+ }
3184+
3185+ #[ unstable( feature = "into_chars" , reason = "new API" , issue = "none" ) ]
3186+ impl FusedIterator for IntoChars { }
3187+
30973188/// A draining iterator for `String`.
30983189///
30993190/// This struct is created by the [`drain`] method on [`String`]. See its
0 commit comments