@@ -97,12 +97,8 @@ impl<Ck: Checksum> Engine<Ck> {
9797
9898 /// Feeds `hrp` into the checksum engine.
9999 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)
106102 }
107103 }
108104
@@ -200,3 +196,63 @@ macro_rules! impl_packed_fe32 {
200196impl_packed_fe32 ! ( u32 ) ;
201197impl_packed_fe32 ! ( u64 ) ;
202198impl_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