@@ -62,9 +62,10 @@ use crate::alloc::Allocator;
62
62
use crate :: borrow:: { Cow , ToOwned } ;
63
63
use crate :: boxed:: Box ;
64
64
use 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 } ;
66
66
#[ cfg( not( no_global_oom_handling) ) ]
67
67
use crate :: str:: { FromStr , from_boxed_utf8_unchecked} ;
68
+ use crate :: vec;
68
69
use crate :: vec:: Vec ;
69
70
70
71
/// A UTF-8–encoded, growable string.
@@ -3094,6 +3095,90 @@ impl fmt::Write for String {
3094
3095
}
3095
3096
}
3096
3097
3098
+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3099
+ pub struct IntoChars {
3100
+ bytes : Vec < u8 > ,
3101
+ }
3102
+
3103
+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3104
+ impl fmt:: Debug for IntoChars {
3105
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
3106
+ f. debug_tuple ( "IntoChars" ) . field ( & self . as_str ( ) ) . finish ( )
3107
+ }
3108
+ }
3109
+
3110
+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3111
+ impl IntoChars {
3112
+ pub fn as_str ( & self ) -> & str {
3113
+ // SAFETY: `bytes` is a valid UTF-8 string.
3114
+ unsafe { str:: from_utf8_unchecked ( self . bytes . as_slice ( ) ) }
3115
+ }
3116
+
3117
+ fn iter ( & self ) -> CharIndices {
3118
+ self . as_str ( ) . char_indices ( )
3119
+ }
3120
+ }
3121
+
3122
+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3123
+ impl AsRef < str > for IntoChars {
3124
+ fn as_ref ( & self ) -> & str {
3125
+ self . as_str ( )
3126
+ }
3127
+ }
3128
+
3129
+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3130
+ impl AsRef < [ u8 ] > for IntoChars {
3131
+ fn as_ref ( & self ) -> & [ u8 ] {
3132
+ self . bytes . as_slice ( )
3133
+ }
3134
+ }
3135
+
3136
+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3137
+ impl Iterator for IntoChars {
3138
+ type Item = char ;
3139
+
3140
+ #[ inline]
3141
+ fn next ( & mut self ) -> Option < char > {
3142
+ let mut iter = self . iter ( ) ;
3143
+ match iter. next ( ) {
3144
+ None => None ,
3145
+ Some ( ( _, ch) ) => {
3146
+ let offset = iter. offset ( ) ;
3147
+ drop ( self . bytes . drain ( ..offset) ) ;
3148
+ Some ( ch)
3149
+ }
3150
+ }
3151
+ }
3152
+
3153
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
3154
+ self . iter ( ) . size_hint ( )
3155
+ }
3156
+
3157
+ #[ inline]
3158
+ fn last ( mut self ) -> Option < char > {
3159
+ self . next_back ( )
3160
+ }
3161
+ }
3162
+
3163
+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3164
+ impl DoubleEndedIterator for IntoChars {
3165
+ #[ inline]
3166
+ fn next_back ( & mut self ) -> Option < char > {
3167
+ let mut iter = self . iter ( ) ;
3168
+ match iter. next_back ( ) {
3169
+ None => None ,
3170
+ Some ( ( idx, ch) ) => {
3171
+ self . bytes . truncate ( idx) ;
3172
+ Some ( ch)
3173
+ }
3174
+ }
3175
+ }
3176
+ }
3177
+
3178
+ #[ unstable( feature = "into_chars" , reason = "new API" , issue="0" ) ]
3179
+ impl FusedIterator for IntoChars { }
3180
+
3181
+
3097
3182
/// A draining iterator for `String`.
3098
3183
///
3099
3184
/// This struct is created by the [`drain`] method on [`String`]. See its
0 commit comments