Skip to main content

utf8_iter/
macros.rs

1// Copyright Mozilla Foundation
2//
3// Licensed under the Apache License (Version 2.0), or the MIT license,
4// (the "Licenses") at your option. You may not use this file except in
5// compliance with one of the Licenses. You may obtain copies of the
6// Licenses at:
7//
8//    https://www.apache.org/licenses/LICENSE-2.0
9//    https://opensource.org/licenses/MIT
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the Licenses is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the Licenses for the specific language governing permissions and
15// limitations under the Licenses.
16
17macro_rules! named_iterators_from_no_argument_handler {
18    ($handler:ident,
19     $item:ty, // For not having to reference private `$handler` in public `Iterator::Type`
20     $(#[$chars_meta:meta])*,
21     $chars:ident,
22     $(#[$chars_indices_meta:meta])*,
23     $char_indices:ident,
24    ) => (
25        $(#[$chars_meta])*
26        #[derive(Debug)]
27        pub struct $chars<'a> {
28            inner: crate::Utf8CharsWithHandler<'a, $handler>,
29        }
30
31        impl<'a> $chars<'a> {
32            #[inline(always)]
33            /// Creates the iterator from a byte slice.
34            pub fn new(bytes: &'a [u8]) -> Self {
35                Self {
36                    inner: crate::Utf8CharsWithHandler::new(bytes, $handler::new()),
37                }
38            }
39
40            /// Views the current remaining data in the iterator as a subslice
41            /// of the original slice.
42            #[must_use]
43            #[inline(always)]
44            pub fn as_slice(&self) -> &'a [u8] {
45                self.inner.as_slice()
46            }
47        }
48
49        impl<'a> Iterator for $chars<'a> {
50            type Item = $item;
51
52            #[inline(always)]
53            fn next(&mut self) -> Option<Self::Item> {
54                self.inner.next()
55            }
56
57            #[inline(always)]
58            fn count(self) -> usize {
59                self.inner.count()
60            }
61
62            #[inline(always)]
63            fn size_hint(&self) -> (usize, Option<usize>) {
64                self.inner.size_hint()
65            }
66
67            #[inline(always)]
68            fn last(mut self) -> Option<Self::Item> {
69                // No need to go through the entire string.
70                self.next_back()
71            }
72        }
73
74        impl<'a> DoubleEndedIterator for $chars<'a> {
75            #[inline(always)]
76            fn next_back(&mut self) -> Option<Self::Item> {
77                self.inner.next_back()
78            }
79        }
80
81        impl core::iter::FusedIterator for $chars<'_> {}
82
83        impl<'a> Clone for $chars<'a> {
84            fn clone(&self) -> Self {
85                Self {
86                    inner: self.inner.clone(),
87                }
88            }
89        }
90
91        $(#[$chars_indices_meta])*
92        #[derive(Debug)]
93        pub struct $char_indices<'a> {
94            inner: crate::Utf8CharIndicesWithHandler<'a, $handler>,
95        }
96
97        impl<'a> $char_indices<'a> {
98            #[inline(always)]
99            /// Creates the iterator from a byte slice.
100            pub fn new(bytes: &'a [u8]) -> Self {
101                Self {
102                    inner: crate::Utf8CharIndicesWithHandler::new(bytes, $handler::new()),
103                }
104            }
105
106            /// Views the current remaining data in the iterator as a subslice
107            /// of the original slice.
108            #[inline(always)]
109            #[must_use]
110            pub fn as_slice(&self) -> &'a [u8] {
111                self.inner.as_slice()
112            }
113
114            /// The current index offset
115            #[inline(always)]
116            #[must_use]
117            pub fn offset(&self) -> usize {
118                self.inner.offset()
119            }
120        }
121
122        impl<'a> Iterator for $char_indices<'a> {
123            type Item = (usize, $item);
124
125            #[inline(always)]
126            fn next(&mut self) -> Option<Self::Item> {
127                self.inner.next()
128            }
129
130            #[inline(always)]
131            fn count(self) -> usize {
132                self.inner.count()
133            }
134
135            #[inline(always)]
136            fn size_hint(&self) -> (usize, Option<usize>) {
137                self.inner.size_hint()
138            }
139
140            #[inline(always)]
141            fn last(mut self) -> Option<Self::Item> {
142                // No need to go through the entire string.
143                self.next_back()
144            }
145        }
146
147        impl<'a> DoubleEndedIterator for $char_indices<'a> {
148            #[inline(always)]
149            fn next_back(&mut self) -> Option<Self::Item> {
150                self.inner.next_back()
151            }
152        }
153
154        impl core::iter::FusedIterator for $char_indices<'_> {}
155
156        impl<'a> Clone for $char_indices<'a> {
157            fn clone(&self) -> Self {
158                Self {
159                    inner: self.inner.clone(),
160                }
161            }
162        }
163    )
164}
165
166pub(crate) use named_iterators_from_no_argument_handler;