@@ -355,6 +355,7 @@ pub struct TomlManifest {
355
355
patch : Option < BTreeMap < String , BTreeMap < String , TomlDependency > > > ,
356
356
workspace : Option < TomlWorkspace > ,
357
357
badges : Option < MaybeWorkspaceBtreeMap > ,
358
+ lints : Option < MaybeWorkspaceLints > ,
358
359
}
359
360
360
361
#[ derive( Deserialize , Serialize , Clone , Debug , Default ) ]
@@ -1421,6 +1422,29 @@ impl<'de> de::Deserialize<'de> for MaybeWorkspaceBtreeMap {
1421
1422
}
1422
1423
}
1423
1424
1425
+ type MaybeWorkspaceLints = MaybeWorkspace < TomlLints , TomlWorkspaceField > ;
1426
+
1427
+ impl < ' de > de:: Deserialize < ' de > for MaybeWorkspaceLints {
1428
+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
1429
+ where
1430
+ D : de:: Deserializer < ' de > ,
1431
+ {
1432
+ let value = serde_value:: Value :: deserialize ( deserializer) ?;
1433
+
1434
+ if let Ok ( w) = TomlWorkspaceField :: deserialize (
1435
+ serde_value:: ValueDeserializer :: < D :: Error > :: new ( value. clone ( ) ) ,
1436
+ ) {
1437
+ return if w. workspace ( ) {
1438
+ Ok ( MaybeWorkspace :: Workspace ( w) )
1439
+ } else {
1440
+ Err ( de:: Error :: custom ( "`workspace` cannot be false" ) )
1441
+ } ;
1442
+ }
1443
+ BTreeMap :: deserialize ( serde_value:: ValueDeserializer :: < D :: Error > :: new ( value) )
1444
+ . map ( MaybeWorkspace :: Defined )
1445
+ }
1446
+ }
1447
+
1424
1448
#[ derive( Deserialize , Serialize , Clone , Debug ) ]
1425
1449
pub struct TomlWorkspaceField {
1426
1450
#[ serde( deserialize_with = "bool_no_false" ) ]
@@ -1507,6 +1531,7 @@ pub struct TomlWorkspace {
1507
1531
// Properties that can be inherited by members.
1508
1532
package : Option < InheritableFields > ,
1509
1533
dependencies : Option < BTreeMap < String , TomlDependency > > ,
1534
+ lints : Option < TomlLints > ,
1510
1535
1511
1536
// Note that this field must come last due to the way toml serialization
1512
1537
// works which requires tables to be emitted after all values.
@@ -1520,6 +1545,9 @@ pub struct InheritableFields {
1520
1545
// and we don't want it present when serializing
1521
1546
#[ serde( skip) ]
1522
1547
dependencies : Option < BTreeMap < String , TomlDependency > > ,
1548
+ #[ serde( skip) ]
1549
+ lints : Option < TomlLints > ,
1550
+
1523
1551
version : Option < semver:: Version > ,
1524
1552
authors : Option < Vec < String > > ,
1525
1553
description : Option < String > ,
@@ -1550,6 +1578,10 @@ impl InheritableFields {
1550
1578
self . dependencies = deps;
1551
1579
}
1552
1580
1581
+ pub fn update_lints ( & mut self , lints : Option < TomlLints > ) {
1582
+ self . lints = lints;
1583
+ }
1584
+
1553
1585
pub fn update_ws_path ( & mut self , ws_root : PathBuf ) {
1554
1586
self . ws_root = ws_root;
1555
1587
}
@@ -1561,6 +1593,12 @@ impl InheritableFields {
1561
1593
)
1562
1594
}
1563
1595
1596
+ pub fn lints ( & self ) -> CargoResult < TomlLints > {
1597
+ self . lints
1598
+ . clone ( )
1599
+ . map_or ( Err ( anyhow ! ( "`workspace.lints` was not defined" ) ) , |d| Ok ( d) )
1600
+ }
1601
+
1564
1602
pub fn get_dependency ( & self , name : & str , package_root : & Path ) -> CargoResult < TomlDependency > {
1565
1603
self . dependencies . clone ( ) . map_or (
1566
1604
Err ( anyhow ! ( "`workspace.dependencies` was not defined" ) ) ,
@@ -1878,6 +1916,7 @@ impl TomlManifest {
1878
1916
workspace : None ,
1879
1917
badges : self . badges . clone ( ) ,
1880
1918
cargo_features : self . cargo_features . clone ( ) ,
1919
+ lints : self . lints . clone ( ) ,
1881
1920
} ) ;
1882
1921
1883
1922
fn map_deps (
@@ -2006,6 +2045,8 @@ impl TomlManifest {
2006
2045
let mut inheritable = toml_config. package . clone ( ) . unwrap_or_default ( ) ;
2007
2046
inheritable. update_ws_path ( package_root. to_path_buf ( ) ) ;
2008
2047
inheritable. update_deps ( toml_config. dependencies . clone ( ) ) ;
2048
+ verify_lints ( toml_config. lints . as_ref ( ) , & features) ?;
2049
+ inheritable. update_lints ( toml_config. lints . clone ( ) ) ;
2009
2050
if let Some ( ws_deps) = & inheritable. dependencies {
2010
2051
for ( name, dep) in ws_deps {
2011
2052
unused_dep_keys (
@@ -2269,6 +2310,13 @@ impl TomlManifest {
2269
2310
& inherit_cell,
2270
2311
) ?;
2271
2312
2313
+ let lints = me
2314
+ . lints
2315
+ . clone ( )
2316
+ . map ( |mw| mw. resolve ( "lints" , || inherit ( ) ?. lints ( ) ) )
2317
+ . transpose ( ) ?;
2318
+ verify_lints ( lints. as_ref ( ) , & features) ?;
2319
+
2272
2320
let mut target: BTreeMap < String , TomlPlatform > = BTreeMap :: new ( ) ;
2273
2321
for ( name, platform) in me. target . iter ( ) . flatten ( ) {
2274
2322
cx. platform = {
@@ -2566,6 +2614,7 @@ impl TomlManifest {
2566
2614
. badges
2567
2615
. as_ref ( )
2568
2616
. map ( |_| MaybeWorkspace :: Defined ( metadata. badges . clone ( ) ) ) ,
2617
+ lints : lints. map ( |lints| MaybeWorkspace :: Defined ( lints) ) ,
2569
2618
} ;
2570
2619
let mut manifest = Manifest :: new (
2571
2620
summary,
@@ -2695,6 +2744,8 @@ impl TomlManifest {
2695
2744
let mut inheritable = toml_config. package . clone ( ) . unwrap_or_default ( ) ;
2696
2745
inheritable. update_ws_path ( root. to_path_buf ( ) ) ;
2697
2746
inheritable. update_deps ( toml_config. dependencies . clone ( ) ) ;
2747
+ verify_lints ( toml_config. lints . as_ref ( ) , & features) ?;
2748
+ inheritable. update_lints ( toml_config. lints . clone ( ) ) ;
2698
2749
let ws_root_config = WorkspaceRootConfig :: new (
2699
2750
root,
2700
2751
& toml_config. members ,
@@ -2839,6 +2890,16 @@ impl TomlManifest {
2839
2890
}
2840
2891
}
2841
2892
2893
+ fn verify_lints ( lints : Option < & TomlLints > , features : & Features ) -> CargoResult < ( ) > {
2894
+ if lints. is_none ( ) {
2895
+ return Ok ( ( ) ) ;
2896
+ } ;
2897
+
2898
+ features. require ( Feature :: lints ( ) ) ?;
2899
+
2900
+ Ok ( ( ) )
2901
+ }
2902
+
2842
2903
fn unused_dep_keys (
2843
2904
dep_name : & str ,
2844
2905
kind : & str ,
@@ -3396,3 +3457,31 @@ impl fmt::Debug for PathValue {
3396
3457
self . 0 . fmt ( f)
3397
3458
}
3398
3459
}
3460
+
3461
+ pub type TomlLints = BTreeMap < String , TomlToolLints > ;
3462
+
3463
+ pub type TomlToolLints = BTreeMap < String , TomlLint > ;
3464
+
3465
+ #[ derive( Serialize , Deserialize , Debug , Clone ) ]
3466
+ #[ serde( untagged) ]
3467
+ pub enum TomlLint {
3468
+ Level ( TomlLintLevel ) ,
3469
+ Config ( TomlLintConfig ) ,
3470
+ }
3471
+
3472
+ #[ derive( Serialize , Deserialize , Debug , Clone ) ]
3473
+ #[ serde( rename_all = "kebab-case" ) ]
3474
+ pub struct TomlLintConfig {
3475
+ level : TomlLintLevel ,
3476
+ #[ serde( default ) ]
3477
+ priority : i8 ,
3478
+ }
3479
+
3480
+ #[ derive( Serialize , Deserialize , Debug , Copy , Clone ) ]
3481
+ #[ serde( rename_all = "kebab-case" ) ]
3482
+ pub enum TomlLintLevel {
3483
+ Forbid ,
3484
+ Deny ,
3485
+ Warn ,
3486
+ Allow ,
3487
+ }
0 commit comments