@@ -62,9 +62,10 @@ 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 , Chars , Utf8Error , from_utf8_unchecked_mut, CharIndices } ;
6666#[ cfg( not( no_global_oom_handling) ) ]
6767use crate :: str:: { FromStr , from_boxed_utf8_unchecked} ;
68+ use crate :: vec;
6869use crate :: vec:: Vec ;
6970
7071/// A UTF-8–encoded, growable string.
@@ -1952,6 +1953,12 @@ impl String {
19521953 Drain { start, end, iter : chars_iter, string : self_ptr }
19531954 }
19541955
1956+ /// Placeholder docs.
1957+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
1958+ pub fn into_chars ( self ) -> IntoChars {
1959+ IntoChars { bytes : self . into_bytes ( ) }
1960+ }
1961+
19551962 /// Removes the specified range in the string,
19561963 /// and replaces it with the given string.
19571964 /// The given string doesn't need to be the same length as the range.
@@ -3094,6 +3101,92 @@ impl fmt::Write for String {
30943101 }
30953102}
30963103
3104+ /// Placeholder docs.
3105+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3106+ pub struct IntoChars {
3107+ bytes : Vec < u8 > ,
3108+ }
3109+
3110+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3111+ impl fmt:: Debug for IntoChars {
3112+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
3113+ f. debug_tuple ( "IntoChars" ) . field ( & self . as_str ( ) ) . finish ( )
3114+ }
3115+ }
3116+
3117+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3118+ impl IntoChars {
3119+ /// Placeholder docs.
3120+ pub fn as_str ( & self ) -> & str {
3121+ // SAFETY: `bytes` is a valid UTF-8 string.
3122+ unsafe { str:: from_utf8_unchecked ( self . bytes . as_slice ( ) ) }
3123+ }
3124+
3125+ fn iter ( & self ) -> CharIndices {
3126+ self . as_str ( ) . char_indices ( )
3127+ }
3128+ }
3129+
3130+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3131+ impl AsRef < str > for IntoChars {
3132+ fn as_ref ( & self ) -> & str {
3133+ self . as_str ( )
3134+ }
3135+ }
3136+
3137+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3138+ impl AsRef < [ u8 ] > for IntoChars {
3139+ fn as_ref ( & self ) -> & [ u8 ] {
3140+ self . bytes . as_slice ( )
3141+ }
3142+ }
3143+
3144+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3145+ impl Iterator for IntoChars {
3146+ type Item = char ;
3147+
3148+ #[ inline]
3149+ fn next ( & mut self ) -> Option < char > {
3150+ let mut iter = self . iter ( ) ;
3151+ match iter. next ( ) {
3152+ None => None ,
3153+ Some ( ( _, ch) ) => {
3154+ let offset = iter. offset ( ) ;
3155+ drop ( self . bytes . drain ( ..offset) ) ;
3156+ Some ( ch)
3157+ }
3158+ }
3159+ }
3160+
3161+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
3162+ self . iter ( ) . size_hint ( )
3163+ }
3164+
3165+ #[ inline]
3166+ fn last ( mut self ) -> Option < char > {
3167+ self . next_back ( )
3168+ }
3169+ }
3170+
3171+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3172+ impl DoubleEndedIterator for IntoChars {
3173+ #[ inline]
3174+ fn next_back ( & mut self ) -> Option < char > {
3175+ let mut iter = self . iter ( ) ;
3176+ match iter. next_back ( ) {
3177+ None => None ,
3178+ Some ( ( idx, ch) ) => {
3179+ self . bytes . truncate ( idx) ;
3180+ Some ( ch)
3181+ }
3182+ }
3183+ }
3184+ }
3185+
3186+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3187+ impl FusedIterator for IntoChars { }
3188+
3189+
30973190/// A draining iterator for `String`.
30983191///
30993192/// This struct is created by the [`drain`] method on [`String`]. See its
0 commit comments