Skip to content

Commit 05cae0c

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

File tree

1 file changed

+94
-1
lines changed

1 file changed

+94
-1
lines changed

library/alloc/src/string.rs

+94-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.
@@ -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

Comments
 (0)