Skip to content

Commit 4f37c6f

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

File tree

1 file changed

+92
-1
lines changed

1 file changed

+92
-1
lines changed

library/alloc/src/string.rs

+92-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ 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, CharIndices, Chars, Utf8Error, from_utf8_unchecked_mut};
6666
#[cfg(not(no_global_oom_handling))]
6767
use crate::str::{FromStr, from_boxed_utf8_unchecked};
6868
use 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

Comments
 (0)