@@ -355,6 +355,7 @@ pub struct TomlManifest {
355355 patch : Option < BTreeMap < String , BTreeMap < String , TomlDependency > > > ,
356356 workspace : Option < TomlWorkspace > ,
357357 badges : Option < MaybeWorkspaceBtreeMap > ,
358+ lints : Option < MaybeWorkspaceLints > ,
358359}
359360
360361#[ derive( Deserialize , Serialize , Clone , Debug , Default ) ]
@@ -1421,6 +1422,29 @@ impl<'de> de::Deserialize<'de> for MaybeWorkspaceBtreeMap {
14211422 }
14221423}
14231424
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+
14241448#[ derive( Deserialize , Serialize , Clone , Debug ) ]
14251449pub struct TomlWorkspaceField {
14261450 #[ serde( deserialize_with = "bool_no_false" ) ]
@@ -1507,6 +1531,7 @@ pub struct TomlWorkspace {
15071531 // Properties that can be inherited by members.
15081532 package : Option < InheritableFields > ,
15091533 dependencies : Option < BTreeMap < String , TomlDependency > > ,
1534+ lints : Option < TomlLints > ,
15101535
15111536 // Note that this field must come last due to the way toml serialization
15121537 // works which requires tables to be emitted after all values.
@@ -1520,6 +1545,9 @@ pub struct InheritableFields {
15201545 // and we don't want it present when serializing
15211546 #[ serde( skip) ]
15221547 dependencies : Option < BTreeMap < String , TomlDependency > > ,
1548+ #[ serde( skip) ]
1549+ lints : Option < TomlLints > ,
1550+
15231551 version : Option < semver:: Version > ,
15241552 authors : Option < Vec < String > > ,
15251553 description : Option < String > ,
@@ -1550,6 +1578,10 @@ impl InheritableFields {
15501578 self . dependencies = deps;
15511579 }
15521580
1581+ pub fn update_lints ( & mut self , lints : Option < TomlLints > ) {
1582+ self . lints = lints;
1583+ }
1584+
15531585 pub fn update_ws_path ( & mut self , ws_root : PathBuf ) {
15541586 self . ws_root = ws_root;
15551587 }
@@ -1561,6 +1593,12 @@ impl InheritableFields {
15611593 )
15621594 }
15631595
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+
15641602 pub fn get_dependency ( & self , name : & str , package_root : & Path ) -> CargoResult < TomlDependency > {
15651603 self . dependencies . clone ( ) . map_or (
15661604 Err ( anyhow ! ( "`workspace.dependencies` was not defined" ) ) ,
@@ -1878,6 +1916,7 @@ impl TomlManifest {
18781916 workspace : None ,
18791917 badges : self . badges . clone ( ) ,
18801918 cargo_features : self . cargo_features . clone ( ) ,
1919+ lints : self . lints . clone ( ) ,
18811920 } ) ;
18821921
18831922 fn map_deps (
@@ -2006,6 +2045,8 @@ impl TomlManifest {
20062045 let mut inheritable = toml_config. package . clone ( ) . unwrap_or_default ( ) ;
20072046 inheritable. update_ws_path ( package_root. to_path_buf ( ) ) ;
20082047 inheritable. update_deps ( toml_config. dependencies . clone ( ) ) ;
2048+ verify_lints ( toml_config. lints . as_ref ( ) , & features) ?;
2049+ inheritable. update_lints ( toml_config. lints . clone ( ) ) ;
20092050 if let Some ( ws_deps) = & inheritable. dependencies {
20102051 for ( name, dep) in ws_deps {
20112052 unused_dep_keys (
@@ -2269,6 +2310,13 @@ impl TomlManifest {
22692310 & inherit_cell,
22702311 ) ?;
22712312
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+
22722320 let mut target: BTreeMap < String , TomlPlatform > = BTreeMap :: new ( ) ;
22732321 for ( name, platform) in me. target . iter ( ) . flatten ( ) {
22742322 cx. platform = {
@@ -2566,6 +2614,7 @@ impl TomlManifest {
25662614 . badges
25672615 . as_ref ( )
25682616 . map ( |_| MaybeWorkspace :: Defined ( metadata. badges . clone ( ) ) ) ,
2617+ lints : lints. map ( |lints| MaybeWorkspace :: Defined ( lints) ) ,
25692618 } ;
25702619 let mut manifest = Manifest :: new (
25712620 summary,
@@ -2695,6 +2744,8 @@ impl TomlManifest {
26952744 let mut inheritable = toml_config. package . clone ( ) . unwrap_or_default ( ) ;
26962745 inheritable. update_ws_path ( root. to_path_buf ( ) ) ;
26972746 inheritable. update_deps ( toml_config. dependencies . clone ( ) ) ;
2747+ verify_lints ( toml_config. lints . as_ref ( ) , & features) ?;
2748+ inheritable. update_lints ( toml_config. lints . clone ( ) ) ;
26982749 let ws_root_config = WorkspaceRootConfig :: new (
26992750 root,
27002751 & toml_config. members ,
@@ -2839,6 +2890,16 @@ impl TomlManifest {
28392890 }
28402891}
28412892
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+
28422903fn unused_dep_keys (
28432904 dep_name : & str ,
28442905 kind : & str ,
@@ -3396,3 +3457,31 @@ impl fmt::Debug for PathValue {
33963457 self . 0 . fmt ( f)
33973458 }
33983459}
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