@@ -1146,7 +1146,7 @@ mod tests {
11461146 use crate :: io:: { self , Cursor } ;
11471147 use crate :: prelude:: * ;
11481148 use crate :: ln:: msgs:: DecodeError ;
1149- use crate :: util:: ser:: { Writeable , HighZeroBytesDroppedBigSize , VecWriter } ;
1149+ use crate :: util:: ser:: { MaybeReadable , Readable , Writeable , HighZeroBytesDroppedBigSize , VecWriter } ;
11501150 use bitcoin:: hashes:: hex:: FromHex ;
11511151 use bitcoin:: secp256k1:: PublicKey ;
11521152
@@ -1256,6 +1256,126 @@ mod tests {
12561256 } else { panic ! ( ) ; }
12571257 }
12581258
1259+ enum InnerEnum {
1260+ StructVariantA {
1261+ field : u32 ,
1262+ } ,
1263+ }
1264+
1265+ impl_writeable_tlv_based_enum_upgradable ! ( InnerEnum ,
1266+ ( 0 , StructVariantA ) => {
1267+ ( 0 , field, required) ,
1268+ } ,
1269+ ) ;
1270+
1271+ struct OuterStructOptionalEnum {
1272+ inner_enum : Option < InnerEnum > ,
1273+ other_field : u32 ,
1274+ }
1275+
1276+ impl Readable for OuterStructOptionalEnum {
1277+ fn read < R : io:: Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
1278+ let mut inner_enum = None ;
1279+ let mut other_field = 0 ;
1280+ read_tlv_fields ! ( reader, {
1281+ ( 0 , inner_enum, upgradable_option) ,
1282+ ( 2 , other_field, required) ,
1283+ } ) ;
1284+ Ok ( Self {
1285+ inner_enum,
1286+ other_field,
1287+ } )
1288+ }
1289+ }
1290+
1291+ #[ test]
1292+ fn upgradable_enum_option ( ) {
1293+ let serialized_bytes = & <Vec < u8 > >:: from_hex (
1294+ concat ! (
1295+ "10" , // total outer_struct length
1296+ "00" , // outer_struct inner_enum type
1297+ "08" , // outer_struct inner_enum length
1298+ "01" , // *inner_enum StructVariantA unknown variant id*
1299+ "06" , // inner_enum StructVariantA length
1300+ "00" , // inner_enum StructVariantA field type
1301+ "04" , // inner_enum StructVariantA field length
1302+ "deadbeef" , // inner_enum StructVariantA field value
1303+ "02" , // outer_struct other_field type
1304+ "04" , // outer_struct other_field length
1305+ "1bad1dea" // outer_struct other_field value
1306+ )
1307+ ) . unwrap ( ) [ ..] ;
1308+ let mut s = Cursor :: new ( serialized_bytes) ;
1309+
1310+ let outer_struct: OuterStructOptionalEnum = Readable :: read ( & mut s) . unwrap ( ) ;
1311+ assert ! ( outer_struct. inner_enum. is_none( ) ) ;
1312+ assert_eq ! ( outer_struct. other_field, 0x1bad1dea ) ;
1313+ }
1314+
1315+ struct OuterOuterStruct {
1316+ outer_struct : Option < OuterStructRequiredEnum > ,
1317+ other_field : u32 ,
1318+ }
1319+
1320+ struct OuterStructRequiredEnum {
1321+ #[ allow( unused) ]
1322+ inner_enum : InnerEnum ,
1323+ }
1324+
1325+ impl MaybeReadable for OuterStructRequiredEnum {
1326+ fn read < R : io:: Read > ( reader : & mut R ) -> Result < Option < Self > , DecodeError > {
1327+ let mut inner_enum = crate :: util:: ser:: UpgradableRequired ( None ) ;
1328+ read_tlv_fields ! ( reader, {
1329+ ( 0 , inner_enum, upgradable_required) ,
1330+ } ) ;
1331+ Ok ( Some ( Self {
1332+ inner_enum : inner_enum. 0 . unwrap ( ) ,
1333+ } ) )
1334+ }
1335+ }
1336+
1337+ impl Readable for OuterOuterStruct {
1338+ fn read < R : io:: Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
1339+ let mut outer_struct = None ;
1340+ let mut other_field = 0 ;
1341+ read_tlv_fields ! ( reader, {
1342+ ( 0 , outer_struct, upgradable_option) ,
1343+ ( 2 , other_field, required) ,
1344+ } ) ;
1345+ Ok ( Self {
1346+ outer_struct,
1347+ other_field,
1348+ } )
1349+ }
1350+ }
1351+
1352+ #[ test]
1353+ fn upgradable_enum_required ( ) {
1354+ let serialized_bytes = & <Vec < u8 > >:: from_hex (
1355+ concat ! (
1356+ "13" , // total outer_outer_struct length
1357+ "00" , // outer_outer_struct outer_struct type
1358+ "0b" , // outer_outer_struct outer_struct length
1359+ "0a" , // total outer_struct length
1360+ "00" , // outer_struct inner_enum TLV type
1361+ "08" , // inner_enum length
1362+ "01" , // *inner_enum StructVariantA unknown variant id*
1363+ "06" , // inner_enum StructVariantA length
1364+ "00" , // inner_enum StructVariantA field type
1365+ "04" , // inner_enum StructVariantA field length
1366+ "deadbeef" , // inner_enum StructVariantA field value
1367+ "02" ,
1368+ "04" ,
1369+ "1bad1dea" ,
1370+ )
1371+ ) . unwrap ( ) [ ..] ;
1372+ let mut s = Cursor :: new ( serialized_bytes) ;
1373+
1374+ let outer_outer_struct: OuterOuterStruct = Readable :: read ( & mut s) . unwrap ( ) ;
1375+ assert ! ( outer_outer_struct. outer_struct. is_none( ) ) ;
1376+ assert_eq ! ( outer_outer_struct. other_field, 0x1bad1dea ) ;
1377+ }
1378+
12591379 // BOLT TLV test cases
12601380 fn tlv_reader_n1 ( s : & [ u8 ] ) -> Result < ( Option < HighZeroBytesDroppedBigSize < u64 > > , Option < u64 > , Option < ( PublicKey , u64 , u64 ) > , Option < u16 > ) , DecodeError > {
12611381 let mut s = Cursor :: new ( s) ;
0 commit comments