@@ -115,6 +115,9 @@ macro_rules! check_tlv_order {
115
115
( $last_seen_type: expr, $typ: expr, $type: expr, $field: ident, vec_type) => { {
116
116
// no-op
117
117
} } ;
118
+ ( $last_seen_type: expr, $typ: expr, $type: expr, $field: ident, maybe_readable) => { {
119
+ // no-op
120
+ } } ;
118
121
}
119
122
120
123
macro_rules! check_missing_tlv {
@@ -138,6 +141,9 @@ macro_rules! check_missing_tlv {
138
141
( $last_seen_type: expr, $type: expr, $field: ident, option) => { {
139
142
// no-op
140
143
} } ;
144
+ ( $last_seen_type: expr, $type: expr, $field: ident, maybe_readable) => { {
145
+ // no-op
146
+ } } ;
141
147
}
142
148
143
149
macro_rules! decode_tlv {
@@ -153,6 +159,9 @@ macro_rules! decode_tlv {
153
159
( $reader: expr, $field: ident, option) => { {
154
160
$field = Some ( ser:: Readable :: read( & mut $reader) ?) ;
155
161
} } ;
162
+ ( $reader: expr, $field: ident, maybe_readable) => { {
163
+ $field = ser:: MaybeReadable :: read( & mut $reader) ?;
164
+ } } ;
156
165
}
157
166
158
167
macro_rules! decode_tlv_stream {
@@ -406,7 +415,7 @@ macro_rules! init_tlv_field_var {
406
415
} ;
407
416
( $field: ident, option) => {
408
417
let mut $field = None ;
409
- }
418
+ } ;
410
419
}
411
420
412
421
/// Implements Readable/Writeable for a struct storing it as a set of TLVs
@@ -459,17 +468,7 @@ macro_rules! impl_writeable_tlv_based {
459
468
}
460
469
}
461
470
462
- /// Implement Readable and Writeable for an enum, with struct variants stored as TLVs and tuple
463
- /// variants stored directly.
464
- /// The format is, for example
465
- /// impl_writeable_tlv_based_enum!(EnumName,
466
- /// (0, StructVariantA) => {(0, required_variant_field, required), (1, optional_variant_field, option)},
467
- /// (1, StructVariantB) => {(0, variant_field_a, required), (1, variant_field_b, required), (2, variant_vec_field, vec_type)};
468
- /// (2, TupleVariantA), (3, TupleVariantB),
469
- /// );
470
- /// The type is written as a single byte, followed by any variant data.
471
- /// Attempts to read an unknown type byte result in DecodeError::UnknownRequiredFeature.
472
- macro_rules! impl_writeable_tlv_based_enum {
471
+ macro_rules! _impl_writeable_tlv_based_enum_common {
473
472
( $st: ident, $( ( $variant_id: expr, $variant_name: ident) =>
474
473
{ $( ( $type: expr, $field: ident, $fieldty: tt) ) ,* $( , ) * }
475
474
) ,* $( , ) * ;
@@ -493,6 +492,67 @@ macro_rules! impl_writeable_tlv_based_enum {
493
492
Ok ( ( ) )
494
493
}
495
494
}
495
+ }
496
+ }
497
+
498
+ /// Implement MaybeReadable and Writeable for an enum, with struct variants stored as TLVs and
499
+ /// tuple variants stored directly.
500
+ macro_rules! impl_writeable_tlv_based_enum_upgradable {
501
+ ( $st: ident, $( ( $variant_id: expr, $variant_name: ident) =>
502
+ { $( ( $type: expr, $field: ident, $fieldty: tt) ) ,* $( , ) * }
503
+ ) ,* $( , ) * ) => {
504
+ _impl_writeable_tlv_based_enum_common!( $st,
505
+ $( ( $variant_id, $variant_name) => { $( ( $type, $field, $fieldty) ) ,* } ) ,* ; ) ;
506
+
507
+ impl :: util:: ser:: MaybeReadable for $st {
508
+ fn read<R : :: std:: io:: Read >( reader: & mut R ) -> Result <Option <Self >, :: ln:: msgs:: DecodeError > {
509
+ let id: u8 = :: util:: ser:: Readable :: read( reader) ?;
510
+ match id {
511
+ $( $variant_id => {
512
+ // Because read_tlv_fields creates a labeled loop, we cannot call it twice
513
+ // in the same function body. Instead, we define a closure and call it.
514
+ let f = || {
515
+ $(
516
+ init_tlv_field_var!( $field, $fieldty) ;
517
+ ) *
518
+ read_tlv_fields!( reader, {
519
+ $( ( $type, $field, $fieldty) ) ,*
520
+ } ) ;
521
+ Ok ( Some ( $st:: $variant_name {
522
+ $(
523
+ $field: init_tlv_based_struct_field!( $field, $fieldty)
524
+ ) ,*
525
+ } ) )
526
+ } ;
527
+ f( )
528
+ } ) ,*
529
+ _ if id % 2 == 1 => { Ok ( None ) }
530
+ _ => { Err ( DecodeError :: UnknownRequiredFeature ) ? } ,
531
+ }
532
+ }
533
+ }
534
+
535
+ }
536
+ }
537
+
538
+ /// Implement Readable and Writeable for an enum, with struct variants stored as TLVs and tuple
539
+ /// variants stored directly.
540
+ /// The format is, for example
541
+ /// impl_writeable_tlv_based_enum!(EnumName,
542
+ /// (0, StructVariantA) => {(0, required_variant_field, required), (1, optional_variant_field, option)},
543
+ /// (1, StructVariantB) => {(0, variant_field_a, required), (1, variant_field_b, required), (2, variant_vec_field, vec_type)};
544
+ /// (2, TupleVariantA), (3, TupleVariantB),
545
+ /// );
546
+ /// The type is written as a single byte, followed by any variant data.
547
+ /// Attempts to read an unknown type byte result in DecodeError::UnknownRequiredFeature.
548
+ macro_rules! impl_writeable_tlv_based_enum {
549
+ ( $st: ident, $( ( $variant_id: expr, $variant_name: ident) =>
550
+ { $( ( $type: expr, $field: ident, $fieldty: tt) ) ,* $( , ) * }
551
+ ) ,* $( , ) * ;
552
+ $( ( $tuple_variant_id: expr, $tuple_variant_name: ident) ) ,* $( , ) * ) => {
553
+ _impl_writeable_tlv_based_enum_common!( $st,
554
+ $( ( $variant_id, $variant_name) => { $( ( $type, $field, $fieldty) ) ,* } ) ,* ;
555
+ $( ( $tuple_variant_id, $tuple_variant_name) ) ,* ) ;
496
556
497
557
impl :: util:: ser:: Readable for $st {
498
558
fn read<R : $crate:: io:: Read >( reader: & mut R ) -> Result <Self , :: ln:: msgs:: DecodeError > {
0 commit comments