@@ -97,12 +97,8 @@ impl<Ck: Checksum> Engine<Ck> {
97
97
98
98
/// Feeds `hrp` into the checksum engine.
99
99
pub fn input_hrp ( & mut self , hrp : & Hrp ) {
100
- for b in hrp. lowercase_byte_iter ( ) {
101
- self . input_fe ( Fe32 ( b >> 5 ) ) ;
102
- }
103
- self . input_fe ( Fe32 :: Q ) ;
104
- for b in hrp. lowercase_byte_iter ( ) {
105
- self . input_fe ( Fe32 ( b & 0x1f ) ) ;
100
+ for fe in HrpFe32Iter :: new ( hrp) {
101
+ self . input_fe ( fe)
106
102
}
107
103
}
108
104
@@ -200,3 +196,63 @@ macro_rules! impl_packed_fe32 {
200
196
impl_packed_fe32 ! ( u32 ) ;
201
197
impl_packed_fe32 ! ( u64 ) ;
202
198
impl_packed_fe32 ! ( u128 ) ;
199
+
200
+ /// Iterator that yields the field elements that are input into a checksum algorithm for an [`Hrp`].
201
+ pub struct HrpFe32Iter < ' hrp > {
202
+ /// `None` once the hrp high fes have been yielded.
203
+ high_iter : Option < crate :: hrp:: LowercaseByteIter < ' hrp > > ,
204
+ /// `None` once the hrp low fes have been yielded.
205
+ low_iter : Option < crate :: hrp:: LowercaseByteIter < ' hrp > > ,
206
+ }
207
+
208
+ impl < ' hrp > HrpFe32Iter < ' hrp > {
209
+ /// Creates an iterator that yields the field elements of `hrp` as they are input into the
210
+ /// checksum algorithm.
211
+ pub fn new ( hrp : & ' hrp Hrp ) -> Self {
212
+ let high_iter = hrp. lowercase_byte_iter ( ) ;
213
+ let low_iter = hrp. lowercase_byte_iter ( ) ;
214
+
215
+ Self { high_iter : Some ( high_iter) , low_iter : Some ( low_iter) }
216
+ }
217
+ }
218
+
219
+ impl < ' hrp > Iterator for HrpFe32Iter < ' hrp > {
220
+ type Item = Fe32 ;
221
+ fn next ( & mut self ) -> Option < Fe32 > {
222
+ if let Some ( ref mut high_iter) = & mut self . high_iter {
223
+ match high_iter. next ( ) {
224
+ Some ( high) => return Some ( Fe32 ( high >> 5 ) ) ,
225
+ None => {
226
+ self . high_iter = None ;
227
+ return Some ( Fe32 :: Q ) ;
228
+ }
229
+ }
230
+ }
231
+ if let Some ( ref mut low_iter) = & mut self . low_iter {
232
+ match low_iter. next ( ) {
233
+ Some ( low) => return Some ( Fe32 ( low & 0x1f ) ) ,
234
+ None => self . low_iter = None ,
235
+ }
236
+ }
237
+ None
238
+ }
239
+
240
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
241
+ let high = match & self . high_iter {
242
+ Some ( high_iter) => {
243
+ let ( min, max) = high_iter. size_hint ( ) ;
244
+ ( min + 1 , max. map ( |max| max + 1 ) ) // +1 for the extra Q
245
+ }
246
+ None => ( 0 , Some ( 0 ) ) ,
247
+ } ;
248
+ let low = match & self . low_iter {
249
+ Some ( low_iter) => low_iter. size_hint ( ) ,
250
+ None => ( 0 , Some ( 0 ) ) ,
251
+ } ;
252
+
253
+ let min = high. 0 + 1 + low. 0 ;
254
+ let max = high. 1 . zip ( low. 1 ) . map ( |( high, low) | high + 1 + low) ;
255
+
256
+ ( min, max)
257
+ }
258
+ }
0 commit comments