1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use super::*;

/////////////////////////////////////////////////////////////////////////////

/// An Iterator created by `<RString as IntoIterator>::into_iter`,
/// which yields all the characters from the `RString`,
/// consuming it in the process.
pub struct IntoIter {
    pub(super) _buf: RString,
    pub(super) iter: Chars<'static>,
}

unsafe impl Send for IntoIter {}
unsafe impl Sync for IntoIter {}

impl IntoIter {
    /// Returns a string slice over the remainder of the string that is being iterated over.
    ///
    /// # Example
    ///
    /// ```
    /// use abi_stable::std_types::RString;
    ///
    /// let mut iter = RString::from("abcd").into_iter();
    ///
    /// assert_eq!(iter.as_str(), "abcd");
    ///
    /// assert_eq!(iter.next(), Some('a'));
    /// assert_eq!(iter.as_str(), "bcd");
    ///
    /// assert_eq!(iter.next_back(), Some('d'));
    /// assert_eq!(iter.as_str(), "bc");
    ///
    /// ```
    pub fn as_str(&self) -> &str {
        self.iter.as_str()
    }
}

impl Iterator for IntoIter {
    type Item = char;

    #[inline]
    fn next(&mut self) -> Option<char> {
        self.iter.next()
    }

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

impl DoubleEndedIterator for IntoIter {
    #[inline]
    fn next_back(&mut self) -> Option<char> {
        self.iter.next_back()
    }
}

impl FusedIterator for IntoIter {}

/////////////////////////////////////////////////////////////////////////////

/// An Iterator returned by `RString::drain` ,
/// which removes and yields all the characters in a range from the RString.
pub struct Drain<'a> {
    pub(super) string: *mut RString,
    pub(super) removed: Range<usize>,
    pub(super) iter: Chars<'a>,
    pub(super) variance: PhantomData<&'a mut [char]>,
}

impl<'a> fmt::Debug for Drain<'a> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.pad("Drain { .. }")
    }
}

unsafe impl<'a> Sync for Drain<'a> {}
unsafe impl<'a> Send for Drain<'a> {}

impl<'a> Drain<'a> {
    /// Returns a string slice over the remainder of the string that is being drained.
    ///
    /// # Example
    ///
    /// ```
    /// use abi_stable::std_types::RString;
    ///
    /// let mut string = RString::from("abcdefg");
    /// let mut iter = string.drain(2..6);
    ///
    /// assert_eq!(iter.as_str(), "cdef");
    ///
    /// assert_eq!(iter.next(), Some('c'));
    /// assert_eq!(iter.as_str(), "def");
    ///
    /// assert_eq!(iter.next_back(), Some('f'));
    /// assert_eq!(iter.as_str(), "de");
    ///
    /// drop(iter);
    ///
    /// assert_eq!(string.as_str(), "abg")
    ///
    /// ```
    pub fn as_str(&self) -> &str {
        self.iter.as_str()
    }
}

impl<'a> Drop for Drain<'a> {
    fn drop(&mut self) {
        unsafe {
            let self_vec = &mut (*self.string).inner;
            if self.removed.start <= self.removed.end && self.removed.end <= self_vec.len() {
                self_vec.drain(self.removed.start..self.removed.end);
            }
        }
    }
}

impl<'a> Iterator for Drain<'a> {
    type Item = char;

    #[inline]
    fn next(&mut self) -> Option<char> {
        self.iter.next()
    }

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

impl<'a> DoubleEndedIterator for Drain<'a> {
    #[inline]
    fn next_back(&mut self) -> Option<char> {
        self.iter.next_back()
    }
}

impl<'a> FusedIterator for Drain<'a> {}