1use core::{fmt, iter::FusedIterator, str::Chars};
2
3use crate::LenType;
4
5use super::StringView;
6
7pub struct Drain<'a, LenT: LenType> {
14 pub(super) string: *mut StringView<LenT>,
16 pub(super) start: LenT,
18 pub(super) end: LenT,
20 pub(super) iter: Chars<'a>,
22}
23
24impl<LenT: LenType> fmt::Debug for Drain<'_, LenT> {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 f.debug_tuple("Drain").field(&self.as_str()).finish()
27 }
28}
29
30unsafe impl<LenT: LenType> Sync for Drain<'_, LenT> {}
31unsafe impl<LenT: LenType> Send for Drain<'_, LenT> {}
32
33impl<LenT: LenType> Drop for Drain<'_, LenT> {
34 fn drop(&mut self) {
35 unsafe {
36 let self_vec = (*self.string).as_mut_vec();
39 let start = self.start.into_usize();
40 let end = self.end.into_usize();
41 if start <= end && end <= self_vec.len() {
42 self_vec.drain(start..end);
43 }
44 }
45 }
46}
47
48impl<LenT: LenType> Drain<'_, LenT> {
49 #[must_use]
63 pub fn as_str(&self) -> &str {
64 self.iter.as_str()
65 }
66}
67
68impl<LenT: LenType> AsRef<str> for Drain<'_, LenT> {
69 fn as_ref(&self) -> &str {
70 self.as_str()
71 }
72}
73
74impl<LenT: LenType> AsRef<[u8]> for Drain<'_, LenT> {
75 fn as_ref(&self) -> &[u8] {
76 self.as_str().as_bytes()
77 }
78}
79
80impl<LenT: LenType> Iterator for Drain<'_, LenT> {
81 type Item = char;
82
83 #[inline]
84 fn next(&mut self) -> Option<char> {
85 self.iter.next()
86 }
87
88 fn size_hint(&self) -> (usize, Option<usize>) {
89 self.iter.size_hint()
90 }
91
92 #[inline]
93 fn last(mut self) -> Option<char> {
94 self.next_back()
95 }
96}
97
98impl<LenT: LenType> DoubleEndedIterator for Drain<'_, LenT> {
99 #[inline]
100 fn next_back(&mut self) -> Option<char> {
101 self.iter.next_back()
102 }
103}
104
105impl<LenT: LenType> FusedIterator for Drain<'_, LenT> {}
106
107#[cfg(test)]
108mod tests {
109 use crate::String;
110
111 #[test]
112 fn drain_front() {
113 let mut s = String::<8>::try_from("abcd").unwrap();
114 let mut it = s.drain(..1);
115 assert_eq!(it.next(), Some('a'));
116 drop(it);
117 assert_eq!(s, "bcd");
118 }
119
120 #[test]
121 fn drain_middle() {
122 let mut s = String::<8>::try_from("abcd").unwrap();
123 let mut it = s.drain(1..3);
124 assert_eq!(it.next(), Some('b'));
125 assert_eq!(it.next(), Some('c'));
126 drop(it);
127 assert_eq!(s, "ad");
128 }
129
130 #[test]
131 fn drain_end() {
132 let mut s = String::<8>::try_from("abcd").unwrap();
133 let mut it = s.drain(3..);
134 assert_eq!(it.next(), Some('d'));
135 drop(it);
136 assert_eq!(s, "abc");
137 }
138}