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