1- use alloc:: boxed:: Box ;
21use core:: fmt;
32use core:: fmt:: { Display , Formatter } ;
43use core:: { array, iter} ;
@@ -13,14 +12,27 @@ use super::{
1312 SignedRawBolt11Invoice , TaggedField ,
1413} ;
1514
15+ macro_rules! define_iterator_enum {
16+ ( $name: ident, $( $n: ident) ,* ) => {
17+ enum $name<$( $n: Iterator <Item = Fe32 >, ) * > {
18+ $( $n( $n) , ) *
19+ }
20+ impl <$( $n: Iterator <Item = Fe32 >, ) * > Iterator for $name<$( $n, ) * > {
21+ type Item = Fe32 ;
22+ fn next( & mut self ) -> Option <Fe32 > {
23+ match self {
24+ $( Self :: $n( iter) => iter. next( ) , ) *
25+ }
26+ }
27+ }
28+ }
29+ }
30+
1631/// Objects that can be encoded to base32 (bech32).
1732///
1833/// Private to this crate to avoid polluting the API.
19- pub trait Base32Iterable {
20- /// apoelstra: In future we want to replace this Box<dyn Iterator> with an explicit
21- /// associated type, to avoid the allocation. But we cannot do this until
22- /// Rust 1.65 and GATs since the iterator may contain a reference to self.
23- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > ;
34+ pub ( crate ) trait Base32Iterable {
35+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s ;
2436}
2537
2638/// Interface to calculate the length of the base32 representation before actually serializing
@@ -32,7 +44,7 @@ pub(crate) trait Base32Len: Base32Iterable {
3244// Base32Iterable & Base32Len implementations are here, because the traits are in this module.
3345
3446impl < const N : usize > Base32Iterable for [ u8 ; N ] {
35- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
47+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
3648 self [ ..] . fe_iter ( )
3749 }
3850}
@@ -45,8 +57,8 @@ impl<const N: usize> Base32Len for [u8; N] {
4557}
4658
4759impl Base32Iterable for [ u8 ] {
48- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
49- Box :: new ( self . iter ( ) . copied ( ) . bytes_to_fes ( ) )
60+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
61+ self . iter ( ) . copied ( ) . bytes_to_fes ( )
5062 }
5163}
5264
@@ -58,8 +70,8 @@ impl Base32Len for [u8] {
5870}
5971
6072impl Base32Iterable for Vec < u8 > {
61- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
62- Box :: new ( self . iter ( ) . copied ( ) . bytes_to_fes ( ) )
73+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
74+ self . iter ( ) . copied ( ) . bytes_to_fes ( )
6375 }
6476}
6577
@@ -71,8 +83,8 @@ impl Base32Len for Vec<u8> {
7183}
7284
7385impl Base32Iterable for PaymentSecret {
74- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
75- Box :: new ( self . 0 [ ..] . fe_iter ( ) )
86+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
87+ self . 0 [ ..] . fe_iter ( )
7688 }
7789}
7890
@@ -88,7 +100,7 @@ impl Base32Iterable for Bolt11InvoiceFeatures {
88100 /// starting from the rightmost bit,
89101 /// and taking the resulting 5-bit values in reverse (left-to-right),
90102 /// with the leading 0's skipped.
91- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
103+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
92104 // Fe32 conversion cannot be used, because this packs from right, right-to-left
93105 let mut input_iter = self . le_flags ( ) . iter ( ) ;
94106 // Carry bits, 0..7 bits
@@ -126,7 +138,7 @@ impl Base32Iterable for Bolt11InvoiceFeatures {
126138 output. push ( Fe32 :: try_from ( next_out8 & 31u8 ) . expect ( "<32" ) )
127139 }
128140 // Take result in reverse order, and skip leading 0s
129- Box :: new ( output. into_iter ( ) . rev ( ) . skip_while ( |e| * e == Fe32 :: Q ) )
141+ output. into_iter ( ) . rev ( ) . skip_while ( |e| * e == Fe32 :: Q )
130142 }
131143}
132144
@@ -241,36 +253,35 @@ fn encoded_int_be_base32_size(int: u64) -> usize {
241253}
242254
243255impl Base32Iterable for RawDataPart {
244- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
256+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
245257 let ts_iter = self . timestamp . fe_iter ( ) ;
246258 let fields_iter = self . tagged_fields . iter ( ) . map ( RawTaggedField :: fe_iter) . flatten ( ) ;
247- Box :: new ( ts_iter. chain ( fields_iter) )
259+ ts_iter. chain ( fields_iter)
248260 }
249261}
250262
251263impl Base32Iterable for PositiveTimestamp {
252- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
264+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
253265 let fes = encode_int_be_base32 ( self . as_unix_timestamp ( ) ) ;
254266 debug_assert ! ( fes. len( ) <= 7 , "Invalid timestamp length" ) ;
255267 let to_pad = 7 - fes. len ( ) ;
256- Box :: new ( core:: iter:: repeat ( Fe32 :: Q ) . take ( to_pad) . chain ( fes) )
268+ core:: iter:: repeat ( Fe32 :: Q ) . take ( to_pad) . chain ( fes)
257269 }
258270}
259271
260272impl Base32Iterable for RawTaggedField {
261- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
262- // Annoyingly, when we move to explicit types, we will need an
263- // explicit enum holding the two iterator variants.
273+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
274+ define_iterator_enum ! ( TwoIters , A , B ) ;
264275 match * self {
265- RawTaggedField :: UnknownSemantics ( ref content) => Box :: new ( content. iter ( ) . copied ( ) ) ,
266- RawTaggedField :: KnownSemantics ( ref tagged_field) => tagged_field. fe_iter ( ) ,
276+ RawTaggedField :: UnknownSemantics ( ref content) => TwoIters :: A ( content. iter ( ) . copied ( ) ) ,
277+ RawTaggedField :: KnownSemantics ( ref tagged_field) => TwoIters :: B ( tagged_field. fe_iter ( ) ) ,
267278 }
268279 }
269280}
270281
271282impl Base32Iterable for Sha256 {
272- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
273- Box :: new ( self . 0 [ ..] . fe_iter ( ) )
283+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
284+ self . 0 [ ..] . fe_iter ( )
274285 }
275286}
276287
@@ -281,8 +292,8 @@ impl Base32Len for Sha256 {
281292}
282293
283294impl Base32Iterable for Description {
284- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
285- Box :: new ( self . 0 . 0 . as_bytes ( ) . fe_iter ( ) )
295+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
296+ self . 0 . 0 . as_bytes ( ) . fe_iter ( )
286297 }
287298}
288299
@@ -293,8 +304,8 @@ impl Base32Len for Description {
293304}
294305
295306impl Base32Iterable for PayeePubKey {
296- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
297- Box :: new ( self . serialize ( ) . into_iter ( ) . bytes_to_fes ( ) )
307+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
308+ self . serialize ( ) . into_iter ( ) . bytes_to_fes ( )
298309 }
299310}
300311
@@ -305,8 +316,8 @@ impl Base32Len for PayeePubKey {
305316}
306317
307318impl Base32Iterable for ExpiryTime {
308- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
309- Box :: new ( encode_int_be_base32 ( self . as_seconds ( ) ) )
319+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
320+ encode_int_be_base32 ( self . as_seconds ( ) )
310321 }
311322}
312323
@@ -317,8 +328,8 @@ impl Base32Len for ExpiryTime {
317328}
318329
319330impl Base32Iterable for MinFinalCltvExpiryDelta {
320- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
321- Box :: new ( encode_int_be_base32 ( self . 0 ) )
331+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
332+ encode_int_be_base32 ( self . 0 )
322333 }
323334}
324335
@@ -329,8 +340,8 @@ impl Base32Len for MinFinalCltvExpiryDelta {
329340}
330341
331342impl Base32Iterable for Fallback {
332- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
333- Box :: new ( match * self {
343+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
344+ match * self {
334345 Fallback :: SegWitProgram { version : v, program : ref p } => {
335346 let v = Fe32 :: try_from ( v. to_num ( ) ) . expect ( "valid version" ) ;
336347 core:: iter:: once ( v) . chain ( p[ ..] . fe_iter ( ) )
@@ -343,7 +354,7 @@ impl Base32Iterable for Fallback {
343354 // 18 'J'
344355 core:: iter:: once ( Fe32 :: J ) . chain ( hash[ ..] . fe_iter ( ) )
345356 } ,
346- } )
357+ }
347358 }
348359}
349360
@@ -371,7 +382,7 @@ type RouteHintHopIter = iter::Chain<
371382> ;
372383
373384impl Base32Iterable for PrivateRoute {
374- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
385+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
375386 fn serialize_to_iter ( hop : & RouteHintHop ) -> RouteHintHopIter {
376387 let i1 = hop. src_node_id . serialize ( ) . into_iter ( ) ;
377388 let i2 = u64:: to_be_bytes ( hop. short_channel_id ) . into_iter ( ) ;
@@ -381,7 +392,7 @@ impl Base32Iterable for PrivateRoute {
381392 i1. chain ( i2) . chain ( i3) . chain ( i4) . chain ( i5)
382393 }
383394
384- Box :: new ( self . 0 . 0 . iter ( ) . map ( serialize_to_iter) . flatten ( ) . bytes_to_fes ( ) )
395+ self . 0 . 0 . iter ( ) . map ( serialize_to_iter) . flatten ( ) . bytes_to_fes ( )
385396 }
386397}
387398
@@ -391,16 +402,11 @@ impl Base32Len for PrivateRoute {
391402 }
392403}
393404
394- // Shorthand type
395- type TaggedFieldIter < I > = core:: iter:: Chain < core:: array:: IntoIter < Fe32 , 3 > , I > ;
396-
397405impl Base32Iterable for TaggedField {
398- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
406+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
399407 /// Writes a tagged field: tag, length and data. `tag` should be in `0..32` otherwise the
400408 /// function will panic.
401- fn write_tagged_field < ' s , P > (
402- tag : u8 , payload : & ' s P ,
403- ) -> TaggedFieldIter < Box < dyn Iterator < Item = Fe32 > + ' s > >
409+ fn write_tagged_field < ' s , P > ( tag : u8 , payload : & ' s P ) -> impl Iterator < Item = Fe32 > + ' s
404410 where
405411 P : Base32Iterable + Base32Len + ?Sized ,
406412 {
@@ -416,54 +422,49 @@ impl Base32Iterable for TaggedField {
416422 . chain ( payload. fe_iter ( ) )
417423 }
418424
419- // we will also need a giant enum for this
420- Box :: new ( match * self {
425+ define_iterator_enum ! ( ManyIters , A , B , C , D , E , F , G , H , I , J , K ) ;
426+ match * self {
421427 TaggedField :: PaymentHash ( ref hash) => {
422- write_tagged_field ( constants:: TAG_PAYMENT_HASH , hash)
428+ ManyIters :: A ( write_tagged_field ( constants:: TAG_PAYMENT_HASH , hash) )
423429 } ,
424430 TaggedField :: Description ( ref description) => {
425- write_tagged_field ( constants:: TAG_DESCRIPTION , description)
431+ ManyIters :: B ( write_tagged_field ( constants:: TAG_DESCRIPTION , description) )
426432 } ,
427433 TaggedField :: PayeePubKey ( ref pub_key) => {
428- write_tagged_field ( constants:: TAG_PAYEE_PUB_KEY , pub_key)
434+ ManyIters :: C ( write_tagged_field ( constants:: TAG_PAYEE_PUB_KEY , pub_key) )
429435 } ,
430436 TaggedField :: DescriptionHash ( ref hash) => {
431- write_tagged_field ( constants:: TAG_DESCRIPTION_HASH , hash)
437+ ManyIters :: D ( write_tagged_field ( constants:: TAG_DESCRIPTION_HASH , hash) )
432438 } ,
433439 TaggedField :: ExpiryTime ( ref duration) => {
434- write_tagged_field ( constants:: TAG_EXPIRY_TIME , duration)
440+ ManyIters :: E ( write_tagged_field ( constants:: TAG_EXPIRY_TIME , duration) )
435441 } ,
436442 TaggedField :: MinFinalCltvExpiryDelta ( ref expiry) => {
437- write_tagged_field ( constants:: TAG_MIN_FINAL_CLTV_EXPIRY_DELTA , expiry)
443+ ManyIters :: F ( write_tagged_field ( constants:: TAG_MIN_FINAL_CLTV_EXPIRY_DELTA , expiry) )
438444 } ,
439445 TaggedField :: Fallback ( ref fallback_address) => {
440- write_tagged_field ( constants:: TAG_FALLBACK , fallback_address)
446+ ManyIters :: G ( write_tagged_field ( constants:: TAG_FALLBACK , fallback_address) )
441447 } ,
442448 TaggedField :: PrivateRoute ( ref route_hops) => {
443- write_tagged_field ( constants:: TAG_PRIVATE_ROUTE , route_hops)
449+ ManyIters :: H ( write_tagged_field ( constants:: TAG_PRIVATE_ROUTE , route_hops) )
444450 } ,
445451 TaggedField :: PaymentSecret ( ref payment_secret) => {
446- write_tagged_field ( constants:: TAG_PAYMENT_SECRET , payment_secret)
452+ ManyIters :: I ( write_tagged_field ( constants:: TAG_PAYMENT_SECRET , payment_secret) )
447453 } ,
448454 TaggedField :: PaymentMetadata ( ref payment_metadata) => {
449- write_tagged_field ( constants:: TAG_PAYMENT_METADATA , payment_metadata)
455+ ManyIters :: J ( write_tagged_field ( constants:: TAG_PAYMENT_METADATA , payment_metadata) )
450456 } ,
451457 TaggedField :: Features ( ref features) => {
452- write_tagged_field ( constants:: TAG_FEATURES , features)
458+ ManyIters :: K ( write_tagged_field ( constants:: TAG_FEATURES , features) )
453459 } ,
454- } )
460+ }
455461 }
456462}
457463
458464impl Base32Iterable for Bolt11InvoiceSignature {
459- fn fe_iter < ' s > ( & ' s self ) -> Box < dyn Iterator < Item = Fe32 > + ' s > {
465+ fn fe_iter < ' s > ( & ' s self ) -> impl Iterator < Item = Fe32 > + ' s {
460466 let ( recovery_id, signature) = self . 0 . serialize_compact ( ) ;
461- Box :: new (
462- signature
463- . into_iter ( )
464- . chain ( core:: iter:: once ( recovery_id. to_i32 ( ) as u8 ) )
465- . bytes_to_fes ( ) ,
466- )
467+ signature. into_iter ( ) . chain ( core:: iter:: once ( recovery_id. to_i32 ( ) as u8 ) ) . bytes_to_fes ( )
467468 }
468469}
469470
0 commit comments