@@ -11,6 +11,9 @@ macro_rules! encode_tlv {
1111 ( $stream: expr, $type: expr, $field: expr, ( default_value, $default: expr) ) => {
1212 encode_tlv!( $stream, $type, $field, required)
1313 } ;
14+ ( $stream: expr, $type: expr, $field: expr, ( static_value, $value: expr) ) => {
15+ let _ = & $field; // Ensure we "use" the $field
16+ } ;
1417 ( $stream: expr, $type: expr, $field: expr, required) => {
1518 BigSize ( $type) . write( $stream) ?;
1619 BigSize ( $field. serialized_length( ) as u64 ) . write( $stream) ?;
@@ -34,6 +37,17 @@ macro_rules! encode_tlv {
3437 } ;
3538}
3639
40+
41+ macro_rules! check_encoded_tlv_order {
42+ ( $last_type: expr, $type: expr, ( static_value, $value: expr) ) => { } ;
43+ ( $last_type: expr, $type: expr, $fieldty: tt) => {
44+ if let Some ( t) = $last_type {
45+ debug_assert!( t <= $type) ;
46+ }
47+ $last_type = Some ( $type) ;
48+ } ;
49+ }
50+
3751macro_rules! encode_tlv_stream {
3852 ( $stream: expr, { $( ( $type: expr, $field: expr, $fieldty: tt) ) ,* $( , ) * } ) => { {
3953 #[ allow( unused_imports) ]
@@ -52,10 +66,7 @@ macro_rules! encode_tlv_stream {
5266 {
5367 let mut last_seen: Option <u64 > = None ;
5468 $(
55- if let Some ( t) = last_seen {
56- debug_assert!( t <= $type) ;
57- }
58- last_seen = Some ( $type) ;
69+ check_encoded_tlv_order!( last_seen, $type, $fieldty) ;
5970 ) *
6071 }
6172 } }
@@ -65,6 +76,8 @@ macro_rules! get_varint_length_prefixed_tlv_length {
6576 ( $len: expr, $type: expr, $field: expr, ( default_value, $default: expr) ) => {
6677 get_varint_length_prefixed_tlv_length!( $len, $type, $field, required)
6778 } ;
79+ ( $len: expr, $type: expr, $field: expr, ( static_value, $value: expr) ) => {
80+ } ;
6881 ( $len: expr, $type: expr, $field: expr, required) => {
6982 BigSize ( $type) . write( & mut $len) . expect( "No in-memory data may fail to serialize" ) ;
7083 let field_len = $field. serialized_length( ) ;
@@ -108,6 +121,8 @@ macro_rules! check_tlv_order {
108121 $field = $default. into( ) ;
109122 }
110123 } } ;
124+ ( $last_seen_type: expr, $typ: expr, $type: expr, $field: ident, ( static_value, $value: expr) ) => {
125+ } ;
111126 ( $last_seen_type: expr, $typ: expr, $type: expr, $field: ident, required) => { {
112127 #[ allow( unused_comparisons) ] // Note that $type may be 0 making the second comparison always true
113128 let invalid_order = ( $last_seen_type. is_none( ) || $last_seen_type. unwrap( ) < $type) && $typ. 0 > $type;
@@ -140,6 +155,9 @@ macro_rules! check_missing_tlv {
140155 $field = $default. into( ) ;
141156 }
142157 } } ;
158+ ( $last_seen_type: expr, $type: expr, $field: expr, ( static_value, $value: expr) ) => {
159+ $field = $value;
160+ } ;
143161 ( $last_seen_type: expr, $type: expr, $field: ident, required) => { {
144162 #[ allow( unused_comparisons) ] // Note that $type may be 0 making the second comparison always true
145163 let missing_req_type = $last_seen_type. is_none( ) || $last_seen_type. unwrap( ) < $type;
@@ -168,6 +186,8 @@ macro_rules! decode_tlv {
168186 ( $reader: expr, $field: ident, ( default_value, $default: expr) ) => { {
169187 decode_tlv!( $reader, $field, required)
170188 } } ;
189+ ( $reader: expr, $field: ident, ( static_value, $value: expr) ) => { {
190+ } } ;
171191 ( $reader: expr, $field: ident, required) => { {
172192 $field = $crate:: util:: ser:: Readable :: read( & mut $reader) ?;
173193 } } ;
@@ -195,6 +215,11 @@ macro_rules! decode_tlv {
195215 } } ;
196216}
197217
218+ macro_rules! _decode_tlv_stream_match_check {
219+ ( $val: ident, $type: expr, ( static_value, $value: expr) ) => { false } ;
220+ ( $val: ident, $type: expr, $fieldty: tt) => { $val == $type }
221+ }
222+
198223// `$decode_custom_tlv` is a closure that may be optionally provided to handle custom message types.
199224// If it is provided, it will be called with the custom type and the `FixedLengthReader` containing
200225// the message contents. It should return `Ok(true)` if the custom message is successfully parsed,
@@ -264,7 +289,7 @@ macro_rules! decode_tlv_stream_range {
264289 let length: ser:: BigSize = $crate:: util:: ser:: Readable :: read( & mut stream_ref) ?;
265290 let mut s = ser:: FixedLengthReader :: new( & mut stream_ref, length. 0 ) ;
266291 match typ. 0 {
267- $( $type => {
292+ $( _t if _decode_tlv_stream_match_check! ( _t , $type, $fieldty ) => {
268293 decode_tlv!( s, $field, $fieldty) ;
269294 if s. bytes_remain( ) {
270295 s. eat_remaining( ) ?; // Return ShortRead if there's actually not enough bytes
@@ -405,6 +430,9 @@ macro_rules! init_tlv_based_struct_field {
405430 ( $field: ident, ( default_value, $default: expr) ) => {
406431 $field. 0 . unwrap( )
407432 } ;
433+ ( $field: ident, ( static_value, $value: expr) ) => {
434+ $field
435+ } ;
408436 ( $field: ident, option) => {
409437 $field
410438 } ;
@@ -420,6 +448,9 @@ macro_rules! init_tlv_field_var {
420448 ( $field: ident, ( default_value, $default: expr) ) => {
421449 let mut $field = $crate:: util:: ser:: OptionDeserWrapper ( None ) ;
422450 } ;
451+ ( $field: ident, ( static_value, $value: expr) ) => {
452+ let $field;
453+ } ;
423454 ( $field: ident, required) => {
424455 let mut $field = $crate:: util:: ser:: OptionDeserWrapper ( None ) ;
425456 } ;
0 commit comments