@@ -1146,7 +1146,7 @@ mod tests {
1146
1146
use crate :: io:: { self , Cursor } ;
1147
1147
use crate :: prelude:: * ;
1148
1148
use crate :: ln:: msgs:: DecodeError ;
1149
- use crate :: util:: ser:: { Writeable , HighZeroBytesDroppedBigSize , VecWriter } ;
1149
+ use crate :: util:: ser:: { MaybeReadable , Readable , Writeable , HighZeroBytesDroppedBigSize , VecWriter } ;
1150
1150
use bitcoin:: hashes:: hex:: FromHex ;
1151
1151
use bitcoin:: secp256k1:: PublicKey ;
1152
1152
@@ -1256,6 +1256,126 @@ mod tests {
1256
1256
} else { panic ! ( ) ; }
1257
1257
}
1258
1258
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
+
1259
1379
// BOLT TLV test cases
1260
1380
fn tlv_reader_n1 ( s : & [ u8 ] ) -> Result < ( Option < HighZeroBytesDroppedBigSize < u64 > > , Option < u64 > , Option < ( PublicKey , u64 , u64 ) > , Option < u16 > ) , DecodeError > {
1261
1381
let mut s = Cursor :: new ( s) ;
0 commit comments