tiny_str/
iter.rs

1//! Iterators for the TinyString
2
3use core::iter::FusedIterator;
4use core::str::Chars;
5
6use crate::TinyString;
7
8/// Iterator over the characers of a [TinyString]
9///
10/// This struct is built from the [TinyString::into_chars] function
11pub struct TinyStringChars<const N: usize> {
12    buf: tiny_vec::iter::TinyVecIter<u8, N>,
13}
14
15impl<const N: usize> TinyStringChars<N> {
16    /// Casts the remaining portion of this iterator as a str
17    pub fn as_str(&self) -> &str {
18        unsafe { str::from_utf8_unchecked(self.buf.as_slice()) }
19    }
20
21    /// Casts the remaining portion of this iterator as a mutable str
22    pub fn as_mut_str(&mut self) -> &mut str {
23        unsafe { str::from_utf8_unchecked_mut(self.buf.as_mut_slice()) }
24    }
25
26    fn iter(&self) -> Chars<'_> {
27        self.as_str().chars()
28    }
29}
30
31impl<const N: usize> Iterator for TinyStringChars<N> {
32    type Item = char;
33
34    fn next(&mut self) -> Option<Self::Item> {
35        let c = self.iter().next()?;
36        for _ in 0..c.len_utf8() {
37            self.buf.next();
38        }
39        Some(c)
40    }
41
42    fn size_hint(&self) -> (usize, Option<usize>) {
43        self.iter().size_hint()
44    }
45}
46
47impl<const N: usize> DoubleEndedIterator for TinyStringChars<N> {
48    fn next_back(&mut self) -> Option<Self::Item> {
49        let c = self.iter().next_back()?;
50        for _ in 0..c.len_utf8() {
51            self.buf.next_back();
52        }
53        Some(c)
54    }
55}
56
57impl<const N: usize> FusedIterator for TinyStringChars<N> {}
58
59/// Iterator over the bytes of a [TinyString]
60///
61/// This struct is built from the [TinyString::into_bytes] function
62pub struct TinyStringBytes<const N: usize>(tiny_vec::iter::TinyVecIter<u8, N>);
63
64impl<const N: usize> Iterator for TinyStringBytes<N> {
65    type Item = u8;
66
67    fn next(&mut self) -> Option<Self::Item> {
68        self.0.next()
69    }
70
71    fn size_hint(&self) -> (usize, Option<usize>) {
72        self.0.size_hint()
73    }
74}
75
76impl<const N: usize> DoubleEndedIterator for TinyStringBytes<N> {
77    fn next_back(&mut self) -> Option<Self::Item> {
78        self.0.next_back()
79    }
80}
81
82impl<const N: usize> FusedIterator for TinyStringBytes<N> {}
83impl<const N: usize> ExactSizeIterator for TinyStringBytes<N> {}
84
85impl<const N: usize> TinyString<N> {
86    /// Converts this [TinyString] into an iterator over it's chars
87    ///
88    /// # Example
89    /// ```
90    /// use tiny_str::TinyString;
91    ///
92    /// let v = TinyString::<10>::from("Hello :)");
93    ///
94    /// let chars = ['H', 'e', 'l', 'l', 'o', ' ', ':', ')'];
95    /// let collected: Vec<char> = v.into_chars().collect();
96    ///
97    /// assert_eq!(&chars[..], &collected[..]);
98    /// ```
99    pub fn into_chars(self) -> TinyStringChars<N> {
100        TinyStringChars {
101            buf: self.buf.into_iter()
102        }
103    }
104
105    /// Converts this [TinyString] into an iterator over it's bytes
106    ///
107    /// # Example
108    /// ```
109    /// use tiny_str::TinyString;
110    ///
111    /// let v = TinyString::<10>::from("bytes");
112    ///
113    /// let bytes = [b'b', b'y', b't', b'e', b's'];
114    /// let collected: Vec<u8> = v.into_bytes().collect();
115    ///
116    /// assert_eq!(&bytes[..], &collected[..]);
117    /// ```
118    pub fn into_bytes(self) -> TinyStringBytes<N> {
119        TinyStringBytes(self.buf.into_iter())
120    }
121}
122
123impl<const N: usize> IntoIterator for  TinyString<N> {
124    type Item = char;
125
126    type IntoIter = TinyStringChars<N>;
127
128    fn into_iter(self) -> Self::IntoIter {
129        self.into_chars()
130    }
131}