abi_stable/std_types/string/iters.rs
1use super::*;
2
3/////////////////////////////////////////////////////////////////////////////
4
5/// An Iterator created by `<RString as IntoIterator>::into_iter`,
6/// which yields all the characters from the `RString`,
7/// consuming it in the process.
8pub struct IntoIter {
9 pub(super) _buf: RString,
10 pub(super) iter: Chars<'static>,
11}
12
13unsafe impl Send for IntoIter {}
14unsafe impl Sync for IntoIter {}
15
16impl IntoIter {
17 /// Returns a string slice over the remainder of the string that is being iterated over.
18 ///
19 /// # Example
20 ///
21 /// ```
22 /// use abi_stable::std_types::RString;
23 ///
24 /// let mut iter = RString::from("abcd").into_iter();
25 ///
26 /// assert_eq!(iter.as_str(), "abcd");
27 ///
28 /// assert_eq!(iter.next(), Some('a'));
29 /// assert_eq!(iter.as_str(), "bcd");
30 ///
31 /// assert_eq!(iter.next_back(), Some('d'));
32 /// assert_eq!(iter.as_str(), "bc");
33 ///
34 /// ```
35 pub fn as_str(&self) -> &str {
36 self.iter.as_str()
37 }
38}
39
40impl Iterator for IntoIter {
41 type Item = char;
42
43 #[inline]
44 fn next(&mut self) -> Option<char> {
45 self.iter.next()
46 }
47
48 fn size_hint(&self) -> (usize, Option<usize>) {
49 self.iter.size_hint()
50 }
51}
52
53impl DoubleEndedIterator for IntoIter {
54 #[inline]
55 fn next_back(&mut self) -> Option<char> {
56 self.iter.next_back()
57 }
58}
59
60impl FusedIterator for IntoIter {}
61
62/////////////////////////////////////////////////////////////////////////////
63
64/// An Iterator returned by `RString::drain` ,
65/// which removes and yields all the characters in a range from the RString.
66pub struct Drain<'a> {
67 pub(super) string: *mut RString,
68 pub(super) removed: Range<usize>,
69 pub(super) iter: Chars<'a>,
70 pub(super) variance: PhantomData<&'a mut [char]>,
71}
72
73impl<'a> fmt::Debug for Drain<'a> {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 f.pad("Drain { .. }")
76 }
77}
78
79unsafe impl<'a> Sync for Drain<'a> {}
80unsafe impl<'a> Send for Drain<'a> {}
81
82impl<'a> Drain<'a> {
83 /// Returns a string slice over the remainder of the string that is being drained.
84 ///
85 /// # Example
86 ///
87 /// ```
88 /// use abi_stable::std_types::RString;
89 ///
90 /// let mut string = RString::from("abcdefg");
91 /// let mut iter = string.drain(2..6);
92 ///
93 /// assert_eq!(iter.as_str(), "cdef");
94 ///
95 /// assert_eq!(iter.next(), Some('c'));
96 /// assert_eq!(iter.as_str(), "def");
97 ///
98 /// assert_eq!(iter.next_back(), Some('f'));
99 /// assert_eq!(iter.as_str(), "de");
100 ///
101 /// drop(iter);
102 ///
103 /// assert_eq!(string.as_str(), "abg")
104 ///
105 /// ```
106 pub fn as_str(&self) -> &str {
107 self.iter.as_str()
108 }
109}
110
111impl<'a> Drop for Drain<'a> {
112 fn drop(&mut self) {
113 unsafe {
114 let self_vec = &mut (*self.string).inner;
115 if self.removed.start <= self.removed.end && self.removed.end <= self_vec.len() {
116 self_vec.drain(self.removed.start..self.removed.end);
117 }
118 }
119 }
120}
121
122impl<'a> Iterator for Drain<'a> {
123 type Item = char;
124
125 #[inline]
126 fn next(&mut self) -> Option<char> {
127 self.iter.next()
128 }
129
130 fn size_hint(&self) -> (usize, Option<usize>) {
131 self.iter.size_hint()
132 }
133}
134
135impl<'a> DoubleEndedIterator for Drain<'a> {
136 #[inline]
137 fn next_back(&mut self) -> Option<char> {
138 self.iter.next_back()
139 }
140}
141
142impl<'a> FusedIterator for Drain<'a> {}