@@ -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,14 @@ 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+ #[ allow( unused_comparisons) ]
312+ let invalid_order =
313+ ( $last_seen_type. is_none( ) || $last_seen_type. unwrap( ) < $type) && $typ. 0 > $type;
314+ if invalid_order {
315+ $field = Some ( $default) ;
316+ }
317+ } } ;
304318 ( $last_seen_type: expr, $typ: expr, $type: expr, $field: ident, ( static_value, $value: expr) ) => { } ;
305319 ( $last_seen_type: expr, $typ: expr, $type: expr, $field: ident, required) => { {
306320 // Note that $type may be 0 making the second comparison always false
@@ -372,6 +386,13 @@ macro_rules! _check_missing_tlv {
372386 $field = $default. into( ) ;
373387 }
374388 } } ;
389+ ( $last_seen_type: expr, $type: expr, $field: ident, ( default_value_vec, $default: expr) ) => { {
390+ #[ allow( unused_comparisons) ]
391+ let missing_req_type = $last_seen_type. is_none( ) || $last_seen_type. unwrap( ) < $type;
392+ if missing_req_type {
393+ $field = Some ( $default) ;
394+ }
395+ } } ;
375396 ( $last_seen_type: expr, $type: expr, $field: expr, ( static_value, $value: expr) ) => {
376397 $field = $value;
377398 } ;
@@ -440,6 +461,10 @@ macro_rules! _decode_tlv {
440461 ( $outer_reader: expr, $reader: expr, $field: ident, ( default_value, $default: expr) ) => { {
441462 $crate:: _decode_tlv!( $outer_reader, $reader, $field, required)
442463 } } ;
464+ ( $outer_reader: expr, $reader: expr, $field: ident, ( default_value_vec, $default: expr) ) => { {
465+ let f: $crate:: util:: ser:: WithoutLength <Vec <_>> = $crate:: util:: ser:: LengthReadable :: read_from_fixed_length_buffer( & mut $reader) ?;
466+ $field = Some ( f. 0 ) ;
467+ } } ;
443468 ( $outer_reader: expr, $reader: expr, $field: ident, ( static_value, $value: expr) ) => { {
444469 } } ;
445470 ( $outer_reader: expr, $reader: expr, $field: ident, required) => { {
@@ -854,6 +879,9 @@ macro_rules! _init_tlv_based_struct_field {
854879 ( $field: ident, ( default_value, $default: expr) ) => {
855880 $field. 0 . unwrap( )
856881 } ;
882+ ( $field: ident, ( default_value_vec, $default: expr) ) => {
883+ $field. unwrap( )
884+ } ;
857885 ( $field: ident, ( static_value, $value: expr) ) => {
858886 $field
859887 } ;
@@ -905,6 +933,9 @@ macro_rules! _init_tlv_field_var {
905933 ( $field: ident, ( default_value, $default: expr) ) => {
906934 let mut $field = $crate:: util:: ser:: RequiredWrapper ( None ) ;
907935 } ;
936+ ( $field: ident, ( default_value_vec, $default: expr) ) => {
937+ let mut $field: Option <Vec <_>> = None ;
938+ } ;
908939 ( $field: ident, ( static_value, $value: expr) ) => {
909940 let $field;
910941 } ;
@@ -1007,6 +1038,9 @@ macro_rules! _decode_and_build {
10071038///
10081039/// If `$fieldty` is `required`, then `$field` is a required field that is not an [`Option`] nor a [`Vec`].
10091040/// If `$fieldty` is `(default_value, $default)`, then `$field` will be set to `$default` if not present.
1041+ /// If `$fieldty` is `(default_value_vec, $default)`, then `$field` is a [`Vec`] which will be set to `$default`
1042+ /// if not present. Elements are serialized individually without a count prefix (like `optional_vec`),
1043+ /// but unlike `optional_vec` a default value is used when the TLV is absent rather than an empty vec.
10101044/// If `$fieldty` is `(static_value, $static)`, then `$field` will be set to `$static`.
10111045/// If `$fieldty` is `option`, then `$field` is optional field.
10121046/// If `$fieldty` is `upgradable_option`, then `$field` is optional and read via [`MaybeReadable`].
@@ -1019,7 +1053,7 @@ macro_rules! _decode_and_build {
10191053/// `Some`. When reading, an optional field of type `$ty` is read, and after all TLV fields are
10201054/// read, the `$read` closure is called with the `Option<&$ty>` value. The `$read` closure should
10211055/// 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.
1056+ /// `default_value`, `default_value_vec`, or `static_value` fields by referring to the value by name.
10231057/// If `$fieldty` is `(custom, $ty, $read, $write)` then, when writing, the same behavior as
10241058/// `legacy`, above is used. When reading, if a TLV is present, it is read as `$ty` and the
10251059/// `$read` method is called with `Some(decoded_$ty_object)`. If no TLV is present, the field
@@ -1956,6 +1990,53 @@ mod tests {
19561990 assert_eq ! ( read, ExpandedField { new_field: ( 42 , 0 ) } ) ;
19571991 }
19581992
1993+ #[ derive( Debug , PartialEq , Eq ) ]
1994+ struct DefaultValueVecStruct {
1995+ items : Vec < u32 > ,
1996+ }
1997+ impl_writeable_tlv_based ! ( DefaultValueVecStruct , {
1998+ ( 1 , items, ( default_value_vec, Vec :: new( ) ) ) ,
1999+ } ) ;
2000+
2001+ #[ test]
2002+ fn test_default_value_vec ( ) {
2003+ // Non-empty vec round-trips correctly.
2004+ let instance = DefaultValueVecStruct { items : vec ! [ 1 , 2 , 3 ] } ;
2005+ let encoded = instance. encode ( ) ;
2006+ let decoded: DefaultValueVecStruct = Readable :: read ( & mut & encoded[ ..] ) . unwrap ( ) ;
2007+ assert_eq ! ( decoded, instance) ;
2008+
2009+ // Empty TLV stream falls back to the default (empty vec).
2010+ let empty_encoded = <Vec < u8 > >:: from_hex ( "00" ) . unwrap ( ) ; // zero-length TLV stream
2011+ let decoded: DefaultValueVecStruct = Readable :: read ( & mut & empty_encoded[ ..] ) . unwrap ( ) ;
2012+ assert_eq ! ( decoded, DefaultValueVecStruct { items: Vec :: new( ) } ) ;
2013+ }
2014+
2015+ #[ derive( Debug , PartialEq , Eq ) ]
2016+ struct LegacyToVecStruct {
2017+ new_items : Vec < u32 > ,
2018+ }
2019+ impl_writeable_tlv_based ! ( LegacyToVecStruct , {
2020+ ( 0 , old_item, ( legacy, u32 , |_| Ok ( ( ) ) ,
2021+ |us: & LegacyToVecStruct | us. new_items. first( ) . copied( ) ) ) ,
2022+ ( 1 , new_items, ( default_value_vec,
2023+ old_item. map( |v| vec![ v] ) . unwrap_or_default( ) ) ) ,
2024+ } ) ;
2025+
2026+ #[ test]
2027+ fn test_default_value_vec_with_legacy_fallback ( ) {
2028+ // New format: round-trips via the new TLV.
2029+ let instance = LegacyToVecStruct { new_items : vec ! [ 10 , 20 , 30 ] } ;
2030+ let encoded = instance. encode ( ) ;
2031+ let decoded: LegacyToVecStruct = Readable :: read ( & mut & encoded[ ..] ) . unwrap ( ) ;
2032+ assert_eq ! ( decoded, instance) ;
2033+
2034+ // Old format: only the legacy type-0 field is present, falls back via default expression.
2035+ let old_encoded = <Vec < u8 > >:: from_hex ( "0600040000002a" ) . unwrap ( ) ; // TLV len 6, type 0, len 4, value 42u32
2036+ let decoded: LegacyToVecStruct = Readable :: read ( & mut & old_encoded[ ..] ) . unwrap ( ) ;
2037+ assert_eq ! ( decoded, LegacyToVecStruct { new_items: vec![ 42 ] } ) ;
2038+ }
2039+
19592040 #[ test]
19602041 fn required_vec_with_encoding ( ) {
19612042 // Ensure that serializing a required vec with a specified encoding will survive a ser round
0 commit comments