Skip to content

Commit 6a88a24

Browse files
committed
Impl String::into_chars
Signed-off-by: tison <[email protected]>
1 parent a4cedec commit 6a88a24

File tree

1 file changed

+86
-1
lines changed

1 file changed

+86
-1
lines changed

library/alloc/src/string.rs

+86-1
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ use crate::alloc::Allocator;
6262
use crate::borrow::{Cow, ToOwned};
6363
use crate::boxed::Box;
6464
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};
6666
#[cfg(not(no_global_oom_handling))]
6767
use crate::str::{FromStr, from_boxed_utf8_unchecked};
68+
use crate::vec;
6869
use crate::vec::Vec;
6970

7071
/// A UTF-8–encoded, growable string.
@@ -3094,6 +3095,90 @@ impl fmt::Write for String {
30943095
}
30953096
}
30963097

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+
30973182
/// A draining iterator for `String`.
30983183
///
30993184
/// This struct is created by the [`drain`] method on [`String`]. See its

0 commit comments

Comments
 (0)