@@ -1299,8 +1299,13 @@ fn overlapping_env_config() {
1299
1299
}
1300
1300
1301
1301
#[ cargo_test]
1302
- fn overlapping_env_with_defaults ( ) {
1302
+ fn overlapping_env_with_defaults_errors_out ( ) {
1303
1303
// Issue where one key is a prefix of another.
1304
+ // This is a limitation of mapping environment variables on to a hierarchy.
1305
+ // Check that we error out when we hit ambiguity in this way, rather than
1306
+ // the more-surprising defaulting through.
1307
+ // If, in the future, we can handle this more correctly, feel free to delete
1308
+ // this test.
1304
1309
#[ derive( Deserialize , Default ) ]
1305
1310
#[ serde( default , rename_all = "kebab-case" ) ]
1306
1311
struct Ambig {
@@ -1310,10 +1315,8 @@ fn overlapping_env_with_defaults() {
1310
1315
let config = ConfigBuilder :: new ( )
1311
1316
. env ( "CARGO_AMBIG_DEBUG_ASSERTIONS" , "true" )
1312
1317
. build ( ) ;
1313
-
1314
- let s: Ambig = config. get ( "ambig" ) . unwrap ( ) ;
1315
- assert_eq ! ( s. debug_assertions, true ) ;
1316
- assert_eq ! ( s. debug, u32 :: default ( ) ) ;
1318
+ let err = config. get :: < Ambig > ( "ambig" ) . err ( ) . unwrap ( ) ;
1319
+ assert ! ( format!( "{}" , err) . contains( "missing config key `ambig.debug`" ) ) ;
1317
1320
1318
1321
let config = ConfigBuilder :: new ( ) . env ( "CARGO_AMBIG_DEBUG" , "5" ) . build ( ) ;
1319
1322
let s: Ambig = config. get ( "ambig" ) . unwrap ( ) ;
@@ -1340,7 +1343,12 @@ fn struct_with_overlapping_inner_struct_and_defaults() {
1340
1343
}
1341
1344
1342
1345
// Containing struct with a prefix of inner
1343
- // Check that the nested struct can have fields defined by env
1346
+ //
1347
+ // This is a limitation of mapping environment variables on to a hierarchy.
1348
+ // Check that we error out when we hit ambiguity in this way, rather than
1349
+ // the more-surprising defaulting through.
1350
+ // If, in the future, we can handle this more correctly, feel free to delete
1351
+ // this case.
1344
1352
#[ derive( Deserialize , Default ) ]
1345
1353
#[ serde( default ) ]
1346
1354
struct PrefixContainer {
@@ -1350,27 +1358,38 @@ fn struct_with_overlapping_inner_struct_and_defaults() {
1350
1358
let config = ConfigBuilder :: new ( )
1351
1359
. env ( "CARGO_PREFIXCONTAINER_INNER_VALUE" , "12" )
1352
1360
. build ( ) ;
1361
+ let err = config
1362
+ . get :: < PrefixContainer > ( "prefixcontainer" )
1363
+ . err ( )
1364
+ . unwrap ( ) ;
1365
+ assert ! ( format!( "{}" , err) . contains( "missing config key `prefixcontainer.inn`" ) ) ;
1366
+ let config = ConfigBuilder :: new ( )
1367
+ . env ( "CARGO_PREFIXCONTAINER_INNER_VALUE" , "12" )
1368
+ . env ( "CARGO_PREFIXCONTAINER_INN" , "true" )
1369
+ . build ( ) ;
1353
1370
let f: PrefixContainer = config. get ( "prefixcontainer" ) . unwrap ( ) ;
1354
- assert_eq ! ( f. inn, bool :: default ( ) ) ;
1355
1371
assert_eq ! ( f. inner. value, 12 ) ;
1372
+ assert_eq ! ( f. inn, true ) ;
1356
1373
1357
1374
// 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
1375
+ //
1376
+ // This is a limitation of mapping environment variables on to a hierarchy.
1377
+ // Check that we error out when we hit ambiguity in this way, rather than
1378
+ // the more-surprising defaulting through.
1379
+ // If, in the future, we can handle this more correctly, feel free to delete
1380
+ // this case.
1359
1381
#[ derive( Deserialize , Default ) ]
1360
1382
#[ serde( default ) ]
1361
1383
struct InversePrefixContainer {
1362
1384
inner_field : bool ,
1363
1385
inner : Inner ,
1364
1386
}
1365
1387
let config = ConfigBuilder :: new ( )
1366
- . env ( "CARGO_INVERSEREFIXCONTAINER_INNER_VALUE " , "12" )
1388
+ . env ( "CARGO_INVERSEPREFIXCONTAINER_INNER_VALUE " , "12" )
1367
1389
. build ( ) ;
1368
1390
let f: InversePrefixContainer = config. get ( "inverseprefixcontainer" ) . unwrap ( ) ;
1369
1391
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);
1392
+ assert_eq ! ( f. inner. value, 12 ) ;
1374
1393
}
1375
1394
1376
1395
#[ cargo_test]
0 commit comments