use core::{fmt, iter::FusedIterator, ptr::NonNull, str::Chars};
use crate::BumpBox;
pub struct Drain<'a> {
pub(crate) string: NonNull<BumpBox<'a, str>>,
pub(crate) start: usize,
pub(crate) end: usize,
pub(crate) iter: Chars<'a>,
}
impl fmt::Debug for Drain<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Drain").field(&self.as_str()).finish()
}
}
unsafe impl Sync for Drain<'_> {}
unsafe impl Send for Drain<'_> {}
impl Drop for Drain<'_> {
fn drop(&mut self) {
unsafe {
let self_vec = self.string.as_mut().as_mut_bytes();
if self.start <= self.end && self.end <= self_vec.len() {
self_vec.drain(self.start..self.end);
}
}
}
}
impl Drain<'_> {
#[must_use]
pub fn as_str(&self) -> &str {
self.iter.as_str()
}
}
impl AsRef<str> for Drain<'_> {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl AsRef<[u8]> for Drain<'_> {
fn as_ref(&self) -> &[u8] {
self.as_str().as_bytes()
}
}
impl Iterator for Drain<'_> {
type Item = char;
#[inline]
fn next(&mut self) -> Option<char> {
self.iter.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline]
fn last(mut self) -> Option<char> {
self.next_back()
}
}
impl DoubleEndedIterator for Drain<'_> {
#[inline]
fn next_back(&mut self) -> Option<char> {
self.iter.next_back()
}
}
impl FusedIterator for Drain<'_> {}