@@ -21,6 +21,9 @@ macro_rules! _encode_tlv {
2121 ( $stream: expr, $type: expr, $field: expr, ( default_value, $default: expr) $( , $self: ident) ?) => {
2222 $crate:: _encode_tlv!( $stream, $type, $field, required)
2323 } ;
24+ ( $stream: expr, $type: expr, $field: expr, ( default_value_vec, $default: expr) $( , $self: ident) ?) => {
25+ $crate:: _encode_tlv!( $stream, $type, $field, required_vec)
26+ } ;
2427 ( $stream: expr, $type: expr, $field: expr, ( static_value, $value: expr) $( , $self: ident) ?) => {
2528 let _ = & $field; // Ensure we "use" the $field
2629 } ;
@@ -200,6 +203,9 @@ macro_rules! _get_varint_length_prefixed_tlv_length {
200203 ( $len: expr, $type: expr, $field: expr, ( default_value, $default: expr) $( , $self: ident) ?) => {
201204 $crate:: _get_varint_length_prefixed_tlv_length!( $len, $type, $field, required)
202205 } ;
206+ ( $len: expr, $type: expr, $field: expr, ( default_value_vec, $default: expr) $( , $self: ident) ?) => {
207+ $crate:: _get_varint_length_prefixed_tlv_length!( $len, $type, $field, required_vec)
208+ } ;
203209 ( $len: expr, $type: expr, $field: expr, ( static_value, $value: expr) $( , $self: ident) ?) => { } ;
204210 ( $len: expr, $type: expr, $field: expr, required $( , $self: ident) ?) => {
205211 BigSize ( $type) . write( & mut $len) . expect( "No in-memory data may fail to serialize" ) ;
@@ -301,6 +307,15 @@ macro_rules! _check_decoded_tlv_order {
301307 $field = $default. into( ) ;
302308 }
303309 } } ;
310+ ( $last_seen_type: expr, $typ: expr, $type: expr, $field: ident, ( default_value_vec, $default: expr) ) => { {
311+ $crate:: _check_decoded_tlv_order!(
312+ $last_seen_type,
313+ $typ,
314+ $type,
315+ $field,
316+ ( default_value, $default)
317+ ) ;
318+ } } ;
304319 ( $last_seen_type: expr, $typ: expr, $type: expr, $field: ident, ( static_value, $value: expr) ) => { } ;
305320 ( $last_seen_type: expr, $typ: expr, $type: expr, $field: ident, required) => { {
306321 // Note that $type may be 0 making the second comparison always false
@@ -372,6 +387,9 @@ macro_rules! _check_missing_tlv {
372387 $field = $default. into( ) ;
373388 }
374389 } } ;
390+ ( $last_seen_type: expr, $type: expr, $field: ident, ( default_value_vec, $default: expr) ) => { {
391+ $crate:: _check_missing_tlv!( $last_seen_type, $type, $field, ( default_value, $default) ) ;
392+ } } ;
375393 ( $last_seen_type: expr, $type: expr, $field: expr, ( static_value, $value: expr) ) => {
376394 $field = $value;
377395 } ;
@@ -440,6 +458,10 @@ macro_rules! _decode_tlv {
440458 ( $outer_reader: expr, $reader: expr, $field: ident, ( default_value, $default: expr) ) => { {
441459 $crate:: _decode_tlv!( $outer_reader, $reader, $field, required)
442460 } } ;
461+ ( $outer_reader: expr, $reader: expr, $field: ident, ( default_value_vec, $default: expr) ) => { {
462+ let f: $crate:: util:: ser:: WithoutLength <Vec <_>> = $crate:: util:: ser:: LengthReadable :: read_from_fixed_length_buffer( & mut $reader) ?;
463+ $field = $crate:: util:: ser:: RequiredWrapper ( Some ( f. 0 ) ) ;
464+ } } ;
443465 ( $outer_reader: expr, $reader: expr, $field: ident, ( static_value, $value: expr) ) => { {
444466 } } ;
445467 ( $outer_reader: expr, $reader: expr, $field: ident, required) => { {
@@ -854,6 +876,9 @@ macro_rules! _init_tlv_based_struct_field {
854876 ( $field: ident, ( default_value, $default: expr) ) => {
855877 $field. 0 . unwrap( )
856878 } ;
879+ ( $field: ident, ( default_value_vec, $default: expr) ) => {
880+ $crate:: _init_tlv_based_struct_field!( $field, ( default_value, $default) )
881+ } ;
857882 ( $field: ident, ( static_value, $value: expr) ) => {
858883 $field
859884 } ;
@@ -905,6 +930,9 @@ macro_rules! _init_tlv_field_var {
905930 ( $field: ident, ( default_value, $default: expr) ) => {
906931 let mut $field = $crate:: util:: ser:: RequiredWrapper ( None ) ;
907932 } ;
933+ ( $field: ident, ( default_value_vec, $default: expr) ) => {
934+ $crate:: _init_tlv_field_var!( $field, ( default_value, $default) ) ;
935+ } ;
908936 ( $field: ident, ( static_value, $value: expr) ) => {
909937 let $field;
910938 } ;
@@ -1007,6 +1035,9 @@ macro_rules! _decode_and_build {
10071035///
10081036/// If `$fieldty` is `required`, then `$field` is a required field that is not an [`Option`] nor a [`Vec`].
10091037/// If `$fieldty` is `(default_value, $default)`, then `$field` will be set to `$default` if not present.
1038+ /// If `$fieldty` is `(default_value_vec, $default)`, then `$field` is a [`Vec`] which will be set to `$default`
1039+ /// if not present. Elements are serialized individually without a count prefix (like `required_vec`).
1040+ /// The TLV is always written, even if the vec is empty (matching `default_value` behavior).
10101041/// If `$fieldty` is `(static_value, $static)`, then `$field` will be set to `$static`.
10111042/// If `$fieldty` is `option`, then `$field` is optional field.
10121043/// If `$fieldty` is `upgradable_option`, then `$field` is optional and read via [`MaybeReadable`].
@@ -1019,7 +1050,7 @@ macro_rules! _decode_and_build {
10191050/// `Some`. When reading, an optional field of type `$ty` is read, and after all TLV fields are
10201051/// read, the `$read` closure is called with the `Option<&$ty>` value. The `$read` closure should
10211052/// return a `Result<(), DecodeError>`. Legacy field values can be used in later
1022- /// `default_value` or `static_value` fields by referring to the value by name.
1053+ /// `default_value`, `default_value_vec`, or `static_value` fields by referring to the value by name.
10231054/// If `$fieldty` is `(custom, $ty, $read, $write)` then, when writing, the same behavior as
10241055/// `legacy`, above is used. When reading, if a TLV is present, it is read as `$ty` and the
10251056/// `$read` method is called with `Some(decoded_$ty_object)`. If no TLV is present, the field
@@ -1956,6 +1987,59 @@ mod tests {
19561987 assert_eq ! ( read, ExpandedField { new_field: ( 42 , 0 ) } ) ;
19571988 }
19581989
1990+ #[ derive( Debug , PartialEq , Eq ) ]
1991+ struct DefaultValueVecStruct {
1992+ items : Vec < u32 > ,
1993+ }
1994+ impl_writeable_tlv_based ! ( DefaultValueVecStruct , {
1995+ ( 1 , items, ( default_value_vec, vec![ 4 , 5 , 6 ] ) ) ,
1996+ } ) ;
1997+
1998+ #[ test]
1999+ fn test_default_value_vec ( ) {
2000+ // Non-empty vec round-trips correctly.
2001+ let instance = DefaultValueVecStruct { items : vec ! [ 1 , 2 , 3 ] } ;
2002+ let encoded = instance. encode ( ) ;
2003+ let decoded: DefaultValueVecStruct = Readable :: read ( & mut & encoded[ ..] ) . unwrap ( ) ;
2004+ assert_eq ! ( decoded, instance) ;
2005+
2006+ // Empty TLV stream falls back to the default.
2007+ let empty_encoded = <Vec < u8 > >:: from_hex ( "00" ) . unwrap ( ) ; // zero-length TLV stream
2008+ let decoded: DefaultValueVecStruct = Readable :: read ( & mut & empty_encoded[ ..] ) . unwrap ( ) ;
2009+ assert_eq ! ( decoded, DefaultValueVecStruct { items: vec![ 4 , 5 , 6 ] } ) ;
2010+
2011+ // Empty vec round-trips to empty vec (TLV is always written).
2012+ let empty_vec = DefaultValueVecStruct { items : vec ! [ ] } ;
2013+ let encoded = empty_vec. encode ( ) ;
2014+ let decoded: DefaultValueVecStruct = Readable :: read ( & mut & encoded[ ..] ) . unwrap ( ) ;
2015+ assert_eq ! ( decoded, DefaultValueVecStruct { items: vec![ ] } ) ;
2016+ }
2017+
2018+ #[ derive( Debug , PartialEq , Eq ) ]
2019+ struct LegacyToVecStruct {
2020+ new_items : Vec < u32 > ,
2021+ }
2022+ impl_writeable_tlv_based ! ( LegacyToVecStruct , {
2023+ ( 0 , old_item, ( legacy, u32 , |_| Ok ( ( ) ) ,
2024+ |us: & LegacyToVecStruct | us. new_items. first( ) . copied( ) ) ) ,
2025+ ( 1 , new_items, ( default_value_vec,
2026+ old_item. map( |v| vec![ v] ) . unwrap_or_default( ) ) ) ,
2027+ } ) ;
2028+
2029+ #[ test]
2030+ fn test_default_value_vec_with_legacy_fallback ( ) {
2031+ // New format: round-trips via the new TLV.
2032+ let instance = LegacyToVecStruct { new_items : vec ! [ 10 , 20 , 30 ] } ;
2033+ let encoded = instance. encode ( ) ;
2034+ let decoded: LegacyToVecStruct = Readable :: read ( & mut & encoded[ ..] ) . unwrap ( ) ;
2035+ assert_eq ! ( decoded, instance) ;
2036+
2037+ // Old format: only the legacy type-0 field is present, falls back via default expression.
2038+ let old_encoded = <Vec < u8 > >:: from_hex ( "0600040000002a" ) . unwrap ( ) ; // TLV len 6, type 0, len 4, value 42u32
2039+ let decoded: LegacyToVecStruct = Readable :: read ( & mut & old_encoded[ ..] ) . unwrap ( ) ;
2040+ assert_eq ! ( decoded, LegacyToVecStruct { new_items: vec![ 42 ] } ) ;
2041+ }
2042+
19592043 #[ test]
19602044 fn required_vec_with_encoding ( ) {
19612045 // Ensure that serializing a required vec with a specified encoding will survive a ser round
0 commit comments