@@ -427,6 +427,132 @@ macro_rules! impl_writeable_tlv_based {
427
427
}
428
428
}
429
429
430
+ /// Defines a struct for a TLV stream and a similar struct using references for non-primitive types,
431
+ /// implementing [`Readable`] for the former and [`Writeable`] for the latter. Useful as an
432
+ /// intermediary format when reading or writing a type encoded as a TLV stream.
433
+ ///
434
+ /// [`Readable`]: crate::util::ser::Readable
435
+ /// [`Writeable`]: crate::util::ser::Writeable
436
+ macro_rules! tlv_stream {
437
+ ( struct $name: ident {
438
+ $( ( $type: expr, $field: ident : $fieldty: ident$( <$gen: ident>) ?) ) ,* $( , ) *
439
+ } ) => {
440
+ #[ derive( Debug ) ]
441
+ struct $name {
442
+ $(
443
+ $field: Option <tlv_record_type!( $fieldty$( <$gen>) ?) >,
444
+ ) *
445
+ }
446
+
447
+ pub ( crate ) mod reference {
448
+ $(
449
+ tlv_record_import!( $fieldty$( <$gen>) ?) ;
450
+ ) *
451
+
452
+ pub ( crate ) struct $name<' a> {
453
+ $(
454
+ pub ( crate ) $field: Option <tlv_record_ref_type!( $fieldty$( <$gen>) ?) >,
455
+ ) *
456
+ }
457
+
458
+ impl <' a> :: util:: ser:: Writeable for $name<' a> {
459
+ fn write<W : :: util:: ser:: Writer >( & self , writer: & mut W ) -> Result <( ) , $crate:: io:: Error > {
460
+ encode_tlv_stream!( writer, { $( ( $type, self . $field, option) ) ,* } ) ;
461
+ Ok ( ( ) )
462
+ }
463
+ }
464
+ }
465
+
466
+ impl :: util:: ser:: Readable for $name {
467
+ fn read<R : $crate:: io:: Read >( reader: & mut R ) -> Result <Self , :: ln:: msgs:: DecodeError > {
468
+ $(
469
+ init_tlv_field_var!( $field, option) ;
470
+ ) *
471
+ decode_tlv_stream!( reader, { $( ( $type, $field, option) ) ,* } ) ;
472
+
473
+ Ok ( Self {
474
+ $(
475
+ $field: init_tlv_based_struct_field!( $field, option)
476
+ ) ,*
477
+ } )
478
+ }
479
+ }
480
+ }
481
+ }
482
+
483
+ macro_rules! tlv_record_type {
484
+ ( u8 ) => {
485
+ u8
486
+ } ;
487
+ ( u16 ) => {
488
+ :: util:: ser:: HighZeroBytesDroppedBigSize <u16 >
489
+ } ;
490
+ ( u32 ) => {
491
+ :: util:: ser:: HighZeroBytesDroppedBigSize <u32 >
492
+ } ;
493
+ ( u64 ) => {
494
+ :: util:: ser:: HighZeroBytesDroppedBigSize <u64 >
495
+ } ;
496
+ ( char ) => {
497
+ char
498
+ } ;
499
+ ( String ) => {
500
+ :: util:: ser:: WithoutLength <String >
501
+ } ;
502
+ ( Vec <$type: ty>) => {
503
+ :: util:: ser:: WithoutLength <Vec <$type>>
504
+ } ;
505
+ ( $type: ident$( <$gen: ident>) ?) => {
506
+ $type$( <$gen>) ?
507
+ } ;
508
+ }
509
+
510
+ macro_rules! tlv_record_ref_type {
511
+ ( u8 ) => {
512
+ u8
513
+ } ;
514
+ ( u16 ) => {
515
+ :: util:: ser:: HighZeroBytesDroppedBigSize <u16 >
516
+ } ;
517
+ ( u32 ) => {
518
+ :: util:: ser:: HighZeroBytesDroppedBigSize <u32 >
519
+ } ;
520
+ ( u64 ) => {
521
+ :: util:: ser:: HighZeroBytesDroppedBigSize <u64 >
522
+ } ;
523
+ ( char ) => {
524
+ char
525
+ } ;
526
+ ( String ) => {
527
+ :: util:: ser:: WithoutLength <& ' a String >
528
+ } ;
529
+ ( Vec <$type: ty>) => {
530
+ :: util:: ser:: WithoutLength <& ' a Vec <$type>>
531
+ } ;
532
+ ( $type: ident$( <$gen: ident>) ?) => {
533
+ & ' a $type$( <$gen>) ?
534
+ } ;
535
+ }
536
+
537
+ macro_rules! tlv_record_import {
538
+ ( u8 ) => { } ;
539
+ ( u16 ) => { } ;
540
+ ( u32 ) => { } ;
541
+ ( u64 ) => { } ;
542
+ ( char ) => { } ;
543
+ ( String ) => { } ;
544
+ ( Vec <$type: ident>) => {
545
+ tlv_record_import!( $type) ;
546
+ } ;
547
+ ( $type: ident<$gen: ident>) => {
548
+ tlv_record_import!( $type) ;
549
+ tlv_record_import!( $gen) ;
550
+ } ;
551
+ ( $type: ident) => {
552
+ use super :: $type;
553
+ } ;
554
+ }
555
+
430
556
macro_rules! _impl_writeable_tlv_based_enum_common {
431
557
( $st: ident, $( ( $variant_id: expr, $variant_name: ident) =>
432
558
{ $( ( $type: expr, $field: ident, $fieldty: tt) ) ,* $( , ) * }
0 commit comments