@@ -1246,6 +1246,27 @@ fn struct_with_opt_inner_struct() {
1246
1246
assert_eq ! ( f. inner. unwrap( ) . value. unwrap( ) , 12 ) ;
1247
1247
}
1248
1248
1249
+ #[ cargo_test]
1250
+ fn struct_with_default_inner_struct ( ) {
1251
+ // Struct with serde defaults.
1252
+ // Check that can be defined with environment variable.
1253
+ #[ derive( Deserialize , Default ) ]
1254
+ #[ serde( default ) ]
1255
+ struct Inner {
1256
+ value : i32 ,
1257
+ }
1258
+ #[ derive( Deserialize , Default ) ]
1259
+ #[ serde( default ) ]
1260
+ struct Foo {
1261
+ inner : Inner ,
1262
+ }
1263
+ let config = ConfigBuilder :: new ( )
1264
+ . env ( "CARGO_FOO_INNER_VALUE" , "12" )
1265
+ . build ( ) ;
1266
+ let f: Foo = config. get ( "foo" ) . unwrap ( ) ;
1267
+ assert_eq ! ( f. inner. value, 12 ) ;
1268
+ }
1269
+
1249
1270
#[ cargo_test]
1250
1271
fn overlapping_env_config ( ) {
1251
1272
// Issue where one key is a prefix of another.
@@ -1277,6 +1298,81 @@ fn overlapping_env_config() {
1277
1298
assert_eq ! ( s. debug, Some ( 1 ) ) ;
1278
1299
}
1279
1300
1301
+ #[ cargo_test]
1302
+ fn overlapping_env_with_defaults ( ) {
1303
+ // Issue where one key is a prefix of another.
1304
+ #[ derive( Deserialize , Default ) ]
1305
+ #[ serde( default , rename_all = "kebab-case" ) ]
1306
+ struct Ambig {
1307
+ debug : u32 ,
1308
+ debug_assertions : bool ,
1309
+ }
1310
+ let config = ConfigBuilder :: new ( )
1311
+ . env ( "CARGO_AMBIG_DEBUG_ASSERTIONS" , "true" )
1312
+ . build ( ) ;
1313
+
1314
+ let s: Ambig = config. get ( "ambig" ) . unwrap ( ) ;
1315
+ assert_eq ! ( s. debug_assertions, true ) ;
1316
+ assert_eq ! ( s. debug, u32 :: default ( ) ) ;
1317
+
1318
+ let config = ConfigBuilder :: new ( ) . env ( "CARGO_AMBIG_DEBUG" , "5" ) . build ( ) ;
1319
+ let s: Ambig = config. get ( "ambig" ) . unwrap ( ) ;
1320
+ assert_eq ! ( s. debug_assertions, bool :: default ( ) ) ;
1321
+ assert_eq ! ( s. debug, 5 ) ;
1322
+
1323
+ let config = ConfigBuilder :: new ( )
1324
+ . env ( "CARGO_AMBIG_DEBUG" , "1" )
1325
+ . env ( "CARGO_AMBIG_DEBUG_ASSERTIONS" , "true" )
1326
+ . build ( ) ;
1327
+ let s: Ambig = config. get ( "ambig" ) . unwrap ( ) ;
1328
+ assert_eq ! ( s. debug_assertions, true ) ;
1329
+ assert_eq ! ( s. debug, 1 ) ;
1330
+ }
1331
+
1332
+ #[ cargo_test]
1333
+ fn struct_with_overlapping_inner_struct_and_defaults ( ) {
1334
+ // Struct with serde defaults.
1335
+ // Check that can be defined with environment variable.
1336
+ #[ derive( Deserialize , Default ) ]
1337
+ #[ serde( default ) ]
1338
+ struct Inner {
1339
+ value : i32 ,
1340
+ }
1341
+
1342
+ // Containing struct with a prefix of inner
1343
+ // Check that the nested struct can have fields defined by env
1344
+ #[ derive( Deserialize , Default ) ]
1345
+ #[ serde( default ) ]
1346
+ struct PrefixContainer {
1347
+ inn : bool ,
1348
+ inner : Inner ,
1349
+ }
1350
+ let config = ConfigBuilder :: new ( )
1351
+ . env ( "CARGO_PREFIXCONTAINER_INNER_VALUE" , "12" )
1352
+ . build ( ) ;
1353
+ let f: PrefixContainer = config. get ( "prefixcontainer" ) . unwrap ( ) ;
1354
+ assert_eq ! ( f. inn, bool :: default ( ) ) ;
1355
+ assert_eq ! ( f. inner. value, 12 ) ;
1356
+
1357
+ // Containing struct where the inner value's field is a prefix of another
1358
+ // Check that the nested struct can have fields defined by env
1359
+ #[ derive( Deserialize , Default ) ]
1360
+ #[ serde( default ) ]
1361
+ struct InversePrefixContainer {
1362
+ inner_field : bool ,
1363
+ inner : Inner ,
1364
+ }
1365
+ let config = ConfigBuilder :: new ( )
1366
+ . env ( "CARGO_INVERSEREFIXCONTAINER_INNER_VALUE" , "12" )
1367
+ . build ( ) ;
1368
+ let f: InversePrefixContainer = config. get ( "inverseprefixcontainer" ) . unwrap ( ) ;
1369
+ assert_eq ! ( f. inner_field, bool :: default ( ) ) ;
1370
+ // NB. This is a limitation of our env variable parsing. We can't currently
1371
+ // handle situations where just a value of the inner struct is set, but
1372
+ // it's also named as a prefix of another field on the outer struct.
1373
+ // assert_eq!(f.inner.value, 12);
1374
+ }
1375
+
1280
1376
#[ cargo_test]
1281
1377
fn string_list_tricky_env ( ) {
1282
1378
// Make sure StringList handles typed env values.
0 commit comments