@@ -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+ // Note that $type may be 0 making the second comparison always false
312+ #[ allow( unused_comparisons) ]
313+ let invalid_order =
314+ ( $last_seen_type. is_none( ) || $last_seen_type. unwrap( ) < $type) && $typ. 0 > $type;
315+ if invalid_order {
316+ $field = Some ( $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,14 @@ 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+ // Note that $type may be 0 making the second comparison always false
392+ #[ allow( unused_comparisons) ]
393+ let missing_req_type = $last_seen_type. is_none( ) || $last_seen_type. unwrap( ) < $type;
394+ if missing_req_type {
395+ $field = Some ( $default) ;
396+ }
397+ } } ;
375398 ( $last_seen_type: expr, $type: expr, $field: expr, ( static_value, $value: expr) ) => {
376399 $field = $value;
377400 } ;
@@ -440,6 +463,10 @@ macro_rules! _decode_tlv {
440463 ( $outer_reader: expr, $reader: expr, $field: ident, ( default_value, $default: expr) ) => { {
441464 $crate:: _decode_tlv!( $outer_reader, $reader, $field, required)
442465 } } ;
466+ ( $outer_reader: expr, $reader: expr, $field: ident, ( default_value_vec, $default: expr) ) => { {
467+ let f: $crate:: util:: ser:: WithoutLength <Vec <_>> = $crate:: util:: ser:: LengthReadable :: read_from_fixed_length_buffer( & mut $reader) ?;
468+ $field = Some ( f. 0 ) ;
469+ } } ;
443470 ( $outer_reader: expr, $reader: expr, $field: ident, ( static_value, $value: expr) ) => { {
444471 } } ;
445472 ( $outer_reader: expr, $reader: expr, $field: ident, required) => { {
@@ -854,6 +881,9 @@ macro_rules! _init_tlv_based_struct_field {
854881 ( $field: ident, ( default_value, $default: expr) ) => {
855882 $field. 0 . unwrap( )
856883 } ;
884+ ( $field: ident, ( default_value_vec, $default: expr) ) => {
885+ $field. unwrap( )
886+ } ;
857887 ( $field: ident, ( static_value, $value: expr) ) => {
858888 $field
859889 } ;
@@ -905,6 +935,9 @@ macro_rules! _init_tlv_field_var {
905935 ( $field: ident, ( default_value, $default: expr) ) => {
906936 let mut $field = $crate:: util:: ser:: RequiredWrapper ( None ) ;
907937 } ;
938+ ( $field: ident, ( default_value_vec, $default: expr) ) => {
939+ let mut $field: Option <Vec <_>> = None ;
940+ } ;
908941 ( $field: ident, ( static_value, $value: expr) ) => {
909942 let $field;
910943 } ;
@@ -1007,6 +1040,9 @@ macro_rules! _decode_and_build {
10071040///
10081041/// If `$fieldty` is `required`, then `$field` is a required field that is not an [`Option`] nor a [`Vec`].
10091042/// If `$fieldty` is `(default_value, $default)`, then `$field` will be set to `$default` if not present.
1043+ /// If `$fieldty` is `(default_value_vec, $default)`, then `$field` is a [`Vec`] which will be set to `$default`
1044+ /// if not present. Elements are serialized individually without a count prefix (like `required_vec`).
1045+ /// The TLV is always written, even if the vec is empty (matching `default_value` behavior).
10101046/// If `$fieldty` is `(static_value, $static)`, then `$field` will be set to `$static`.
10111047/// If `$fieldty` is `option`, then `$field` is optional field.
10121048/// If `$fieldty` is `upgradable_option`, then `$field` is optional and read via [`MaybeReadable`].
@@ -1019,7 +1055,7 @@ macro_rules! _decode_and_build {
10191055/// `Some`. When reading, an optional field of type `$ty` is read, and after all TLV fields are
10201056/// read, the `$read` closure is called with the `Option<&$ty>` value. The `$read` closure should
10211057/// 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.
1058+ /// `default_value`, `default_value_vec`, or `static_value` fields by referring to the value by name.
10231059/// If `$fieldty` is `(custom, $ty, $read, $write)` then, when writing, the same behavior as
10241060/// `legacy`, above is used. When reading, if a TLV is present, it is read as `$ty` and the
10251061/// `$read` method is called with `Some(decoded_$ty_object)`. If no TLV is present, the field
@@ -1956,6 +1992,59 @@ mod tests {
19561992 assert_eq ! ( read, ExpandedField { new_field: ( 42 , 0 ) } ) ;
19571993 }
19581994
1995+ #[ derive( Debug , PartialEq , Eq ) ]
1996+ struct DefaultValueVecStruct {
1997+ items : Vec < u32 > ,
1998+ }
1999+ impl_writeable_tlv_based ! ( DefaultValueVecStruct , {
2000+ ( 1 , items, ( default_value_vec, vec![ 4 , 5 , 6 ] ) ) ,
2001+ } ) ;
2002+
2003+ #[ test]
2004+ fn test_default_value_vec ( ) {
2005+ // Non-empty vec round-trips correctly.
2006+ let instance = DefaultValueVecStruct { items : vec ! [ 1 , 2 , 3 ] } ;
2007+ let encoded = instance. encode ( ) ;
2008+ let decoded: DefaultValueVecStruct = Readable :: read ( & mut & encoded[ ..] ) . unwrap ( ) ;
2009+ assert_eq ! ( decoded, instance) ;
2010+
2011+ // Empty TLV stream falls back to the default.
2012+ let empty_encoded = <Vec < u8 > >:: from_hex ( "00" ) . unwrap ( ) ; // zero-length TLV stream
2013+ let decoded: DefaultValueVecStruct = Readable :: read ( & mut & empty_encoded[ ..] ) . unwrap ( ) ;
2014+ assert_eq ! ( decoded, DefaultValueVecStruct { items: vec![ 4 , 5 , 6 ] } ) ;
2015+
2016+ // Empty vec round-trips to empty vec (TLV is always written).
2017+ let empty_vec = DefaultValueVecStruct { items : vec ! [ ] } ;
2018+ let encoded = empty_vec. encode ( ) ;
2019+ let decoded: DefaultValueVecStruct = Readable :: read ( & mut & encoded[ ..] ) . unwrap ( ) ;
2020+ assert_eq ! ( decoded, DefaultValueVecStruct { items: vec![ ] } ) ;
2021+ }
2022+
2023+ #[ derive( Debug , PartialEq , Eq ) ]
2024+ struct LegacyToVecStruct {
2025+ new_items : Vec < u32 > ,
2026+ }
2027+ impl_writeable_tlv_based ! ( LegacyToVecStruct , {
2028+ ( 0 , old_item, ( legacy, u32 , |_| Ok ( ( ) ) ,
2029+ |us: & LegacyToVecStruct | us. new_items. first( ) . copied( ) ) ) ,
2030+ ( 1 , new_items, ( default_value_vec,
2031+ old_item. map( |v| vec![ v] ) . unwrap_or_default( ) ) ) ,
2032+ } ) ;
2033+
2034+ #[ test]
2035+ fn test_default_value_vec_with_legacy_fallback ( ) {
2036+ // New format: round-trips via the new TLV.
2037+ let instance = LegacyToVecStruct { new_items : vec ! [ 10 , 20 , 30 ] } ;
2038+ let encoded = instance. encode ( ) ;
2039+ let decoded: LegacyToVecStruct = Readable :: read ( & mut & encoded[ ..] ) . unwrap ( ) ;
2040+ assert_eq ! ( decoded, instance) ;
2041+
2042+ // Old format: only the legacy type-0 field is present, falls back via default expression.
2043+ let old_encoded = <Vec < u8 > >:: from_hex ( "0600040000002a" ) . unwrap ( ) ; // TLV len 6, type 0, len 4, value 42u32
2044+ let decoded: LegacyToVecStruct = Readable :: read ( & mut & old_encoded[ ..] ) . unwrap ( ) ;
2045+ assert_eq ! ( decoded, LegacyToVecStruct { new_items: vec![ 42 ] } ) ;
2046+ }
2047+
19592048 #[ test]
19602049 fn required_vec_with_encoding ( ) {
19612050 // Ensure that serializing a required vec with a specified encoding will survive a ser round
0 commit comments