@@ -47,29 +47,36 @@ macro_rules! encode_tlv {
4747 } }
4848}
4949
50- macro_rules! encode_varint_length_prefixed_tlv {
51- ( $stream : expr , { $( ( $type: expr, $field: expr) ) ,* } , { $( ( $optional_type: expr, $optional_field: expr) ) ,* } ) => { {
52- use util:: ser:: { BigSize , LengthCalculatingWriter } ;
50+ macro_rules! get_varint_length_prefixed_tlv_length {
51+ ( { $( ( $type: expr, $field: expr) ) ,* } , { $( ( $optional_type: expr, $optional_field: expr) ) ,* $ ( , ) * } ) => { {
52+ use util:: ser:: LengthCalculatingWriter ;
5353 #[ allow( unused_mut) ]
5454 let mut len = LengthCalculatingWriter ( 0 ) ;
5555 {
5656 $(
57- BigSize ( $type) . write( & mut len) ? ;
57+ BigSize ( $type) . write( & mut len) . expect ( "No in-memory data may fail to serialize" ) ;
5858 let field_len = $field. serialized_length( ) ;
59- BigSize ( field_len as u64 ) . write( & mut len) ? ;
59+ BigSize ( field_len as u64 ) . write( & mut len) . expect ( "No in-memory data may fail to serialize" ) ;
6060 len. 0 += field_len;
6161 ) *
6262 $(
6363 if let Some ( ref field) = $optional_field {
64- BigSize ( $optional_type) . write( & mut len) ? ;
64+ BigSize ( $optional_type) . write( & mut len) . expect ( "No in-memory data may fail to serialize" ) ;
6565 let field_len = field. serialized_length( ) ;
66- BigSize ( field_len as u64 ) . write( & mut len) ? ;
66+ BigSize ( field_len as u64 ) . write( & mut len) . expect ( "No in-memory data may fail to serialize" ) ;
6767 len. 0 += field_len;
6868 }
6969 ) *
7070 }
71+ len. 0
72+ } }
73+ }
7174
72- BigSize ( len. 0 as u64 ) . write( $stream) ?;
75+ macro_rules! encode_varint_length_prefixed_tlv {
76+ ( $stream: expr, { $( ( $type: expr, $field: expr) ) ,* } , { $( ( $optional_type: expr, $optional_field: expr) ) ,* } ) => { {
77+ use util:: ser:: BigSize ;
78+ let len = get_varint_length_prefixed_tlv_length!( { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* } ) ;
79+ BigSize ( len as u64 ) . write( $stream) ?;
7380 encode_tlv!( $stream, { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* } ) ;
7481 } }
7582}
@@ -167,13 +174,29 @@ macro_rules! impl_writeable {
167174 if $len != 0 {
168175 use util:: ser:: LengthCalculatingWriter ;
169176 let mut len_calc = LengthCalculatingWriter ( 0 ) ;
170- $( self . $field. write( & mut len_calc) ? ; ) *
177+ $( self . $field. write( & mut len_calc) . expect ( "No in-memory data may fail to serialize" ) ; ) *
171178 assert_eq!( len_calc. 0 , $len) ;
179+ assert_eq!( self . serialized_length( ) , $len) ;
172180 }
173181 }
174182 $( self . $field. write( w) ?; ) *
175183 Ok ( ( ) )
176184 }
185+
186+ #[ inline]
187+ fn serialized_length( & self ) -> usize {
188+ if $len == 0 || cfg!( any( test, feature = "fuzztarget" ) ) {
189+ let mut len_calc = 0 ;
190+ $( len_calc += self . $field. serialized_length( ) ; ) *
191+ if $len != 0 {
192+ // In tests, assert that the hard-coded length matches the actual one
193+ assert_eq!( len_calc, $len) ;
194+ } else {
195+ return len_calc;
196+ }
197+ }
198+ $len
199+ }
177200 }
178201
179202 impl :: util:: ser:: Readable for $st {
@@ -186,7 +209,7 @@ macro_rules! impl_writeable {
186209 }
187210}
188211macro_rules! impl_writeable_len_match {
189- ( $struct: ident, $cmp: tt, { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
212+ ( $struct: ident, $cmp: tt, ( $calc_len : expr ) , { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
190213 impl Writeable for $struct {
191214 fn write<W : Writer >( & self , w: & mut W ) -> Result <( ) , :: std:: io:: Error > {
192215 let len = match * self {
@@ -198,12 +221,30 @@ macro_rules! impl_writeable_len_match {
198221 // In tests, assert that the hard-coded length matches the actual one
199222 use util:: ser:: LengthCalculatingWriter ;
200223 let mut len_calc = LengthCalculatingWriter ( 0 ) ;
201- $( self . $field. write( & mut len_calc) ? ; ) *
224+ $( self . $field. write( & mut len_calc) . expect ( "No in-memory data may fail to serialize" ) ; ) *
202225 assert!( len_calc. 0 $cmp len) ;
226+ assert_eq!( len_calc. 0 , self . serialized_length( ) ) ;
203227 }
204228 $( self . $field. write( w) ?; ) *
205229 Ok ( ( ) )
206230 }
231+
232+ #[ inline]
233+ fn serialized_length( & self ) -> usize {
234+ if $calc_len || cfg!( any( test, feature = "fuzztarget" ) ) {
235+ let mut len_calc = 0 ;
236+ $( len_calc += self . $field. serialized_length( ) ; ) *
237+ if !$calc_len {
238+ assert_eq!( len_calc, match * self {
239+ $( $match => $length, ) *
240+ } ) ;
241+ }
242+ return len_calc
243+ }
244+ match * self {
245+ $( $match => $length, ) *
246+ }
247+ }
207248 }
208249
209250 impl :: util:: ser:: Readable for $struct {
@@ -214,8 +255,11 @@ macro_rules! impl_writeable_len_match {
214255 }
215256 }
216257 } ;
258+ ( $struct: ident, $cmp: tt, { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
259+ impl_writeable_len_match!( $struct, $cmp, ( true ) , { $( { $match, $length } ) ,* } , { $( $field) ,* } ) ;
260+ } ;
217261 ( $struct: ident, { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
218- impl_writeable_len_match!( $struct, ==, { $( { $match, $length } ) ,* } , { $( $field) ,* } ) ;
262+ impl_writeable_len_match!( $struct, ==, ( false ) , { $( { $match, $length } ) ,* } , { $( $field) ,* } ) ;
219263 }
220264}
221265
@@ -319,6 +363,14 @@ macro_rules! _write_tlv_fields {
319363 write_tlv_fields!( $stream, { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* , $( ( $optional_type_2, $optional_field_2) ) ,* } ) ;
320364 }
321365}
366+ macro_rules! _get_tlv_len {
367+ ( { $( ( $type: expr, $field: expr) ) ,* $( , ) * } , { } , { $( ( $optional_type: expr, $optional_field: expr) ) ,* $( , ) * } ) => {
368+ get_varint_length_prefixed_tlv_length!( { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* } )
369+ } ;
370+ ( { $( ( $type: expr, $field: expr) ) ,* $( , ) * } , { $( ( $optional_type: expr, $optional_field: expr) ) ,* $( , ) * } , { $( ( $optional_type_2: expr, $optional_field_2: expr) ) ,* $( , ) * } ) => {
371+ get_varint_length_prefixed_tlv_length!( { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* , $( ( $optional_type_2, $optional_field_2) ) ,* } )
372+ }
373+ }
322374macro_rules! _read_tlv_fields {
323375 ( $stream: expr, { $( ( $reqtype: expr, $reqfield: ident) ) ,* $( , ) * } , { } , { $( ( $type: expr, $field: ident) ) ,* $( , ) * } ) => {
324376 read_tlv_fields!( $stream, { $( ( $reqtype, $reqfield) ) ,* } , { $( ( $type, $field) ) ,* } ) ;
@@ -346,6 +398,21 @@ macro_rules! impl_writeable_tlv_based {
346398 } ) ;
347399 Ok ( ( ) )
348400 }
401+
402+ #[ inline]
403+ fn serialized_length( & self ) -> usize {
404+ let len = _get_tlv_len!( {
405+ $( ( $reqtype, self . $reqfield) ) ,*
406+ } , {
407+ $( ( $type, self . $field) ) ,*
408+ } , {
409+ $( ( $vectype, Some ( :: util:: ser:: VecWriteWrapper ( & self . $vecfield) ) ) ) ,*
410+ } ) ;
411+ use util:: ser:: { BigSize , LengthCalculatingWriter } ;
412+ let mut len_calc = LengthCalculatingWriter ( 0 ) ;
413+ BigSize ( len as u64 ) . write( & mut len_calc) . expect( "No in-memory data may fail to serialize" ) ;
414+ len + len_calc. 0
415+ }
349416 }
350417
351418 impl :: util:: ser:: Readable for $st {
0 commit comments