Skip to content

Commit

Permalink
Impl String::into_chars
Browse files Browse the repository at this point in the history
Signed-off-by: tison <wander4096@gmail.com>
  • Loading branch information
tisonkun committed Nov 15, 2024
1 parent a4cedec commit 6a88a24
Showing 1 changed file with 86 additions and 1 deletion.
87 changes: 86 additions & 1 deletion library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ use crate::alloc::Allocator;
use crate::borrow::{Cow, ToOwned};
use crate::boxed::Box;
use crate::collections::TryReserveError;
use crate::str::{self, Chars, Utf8Error, from_utf8_unchecked_mut};
use crate::str::{self, Chars, Utf8Error, from_utf8_unchecked_mut, CharIndices};
#[cfg(not(no_global_oom_handling))]
use crate::str::{FromStr, from_boxed_utf8_unchecked};
use crate::vec;
use crate::vec::Vec;

/// A UTF-8–encoded, growable string.
Expand Down Expand Up @@ -3094,6 +3095,90 @@ impl fmt::Write for String {
}
}

#[unstable(feature = "into_chars", reason = "new API", issue="0")]
pub struct IntoChars {
bytes: Vec<u8>,
}

#[unstable(feature = "into_chars", reason = "new API", issue="0")]
impl fmt::Debug for IntoChars {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("IntoChars").field(&self.as_str()).finish()
}
}

#[unstable(feature = "into_chars", reason = "new API", issue="0")]
impl IntoChars {
pub fn as_str(&self) -> &str {
// SAFETY: `bytes` is a valid UTF-8 string.
unsafe { str::from_utf8_unchecked(self.bytes.as_slice()) }
}

fn iter(&self) -> CharIndices {
self.as_str().char_indices()
}
}

#[unstable(feature = "into_chars", reason = "new API", issue="0")]
impl AsRef<str> for IntoChars {
fn as_ref(&self) -> &str {
self.as_str()
}
}

#[unstable(feature = "into_chars", reason = "new API", issue="0")]
impl AsRef<[u8]> for IntoChars {
fn as_ref(&self) -> &[u8] {
self.bytes.as_slice()
}
}

#[unstable(feature = "into_chars", reason = "new API", issue="0")]
impl Iterator for IntoChars {
type Item = char;

#[inline]
fn next(&mut self) -> Option<char> {
let mut iter = self.iter();
match iter.next() {
None => None,
Some((_, ch)) => {
let offset = iter.offset();
drop(self.bytes.drain(..offset));
Some(ch)
}
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
self.iter().size_hint()
}

#[inline]
fn last(mut self) -> Option<char> {
self.next_back()
}
}

#[unstable(feature = "into_chars", reason = "new API", issue="0")]
impl DoubleEndedIterator for IntoChars {
#[inline]
fn next_back(&mut self) -> Option<char> {
let mut iter = self.iter();
match iter.next_back() {
None => None,
Some((idx, ch)) => {
self.bytes.truncate(idx);
Some(ch)
}
}
}
}

#[unstable(feature = "into_chars", reason = "new API", issue="0")]
impl FusedIterator for IntoChars {}


/// A draining iterator for `String`.
///
/// This struct is created by the [`drain`] method on [`String`]. See its
Expand Down

0 comments on commit 6a88a24

Please sign in to comment.