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> {}