//! Generate lints for Cargo.toml. #![cfg_attr(docsrs, feature(doc_cfg))] extern crate alloc; use anyhow::Result; use clap::Parser as _; use lint_policy::Linter; use lint_policy::cargo::{LintTable, Manifest}; use strum::IntoEnumIterator as _; mod cli; mod diff; mod group; mod source; use cli::Args; use diff::{Diff, diff}; use crate::group::GroupTable; /// An empty lint table for unwrapping table references. static EMPTY_LINTS: LintTable = LintTable::new(); /// An empty group table for unwrapping table references. static EMPTY_GROUPS: GroupTable = GroupTable::new(); #[cfg_attr(test, expect(clippy::missing_errors_doc, reason = "main function"))] fn main() -> Result<()> { let args = Args::parse(); let new_lints = args.read_new_source(); let old_lints = args.read_old_source(); match old_lints { None => { for linter in Linter::iter() { // section #[expect(clippy::print_stdout, reason = "printing out actual output")] { let mut manifest = Manifest::default(); manifest .workspace .lints .set_lints_for(linter, LintTable::default()); print!("{}", toml::to_string(&manifest)?); } // lints if let Some(lints) = new_lints.0.get_lints_for(linter) { let mut value = String::new(); #[expect(clippy::print_stdout, reason = "printing out actual output")] for lint in lints { _ = serde::Serialize::serialize( &lint.1, toml::ser::ValueSerializer::new(&mut value), )?; println!("{} = {}", lint.0, value); value.clear(); } } } } Some(old_lints) => { for linter in Linter::iter() { // section #[expect(clippy::print_stdout, reason = "printing out actual output")] { let mut manifest = Manifest::default(); manifest .workspace .lints .set_lints_for(linter, LintTable::default()); print!("{}", toml::to_string(&manifest)?); } // diff let mut value = String::new(); let old_lints = old_lints.0.get_lints_for(linter).unwrap_or(&EMPTY_LINTS); let (new_lints, new_groups) = ( new_lints.0.get_lints_for(linter).unwrap_or(&EMPTY_LINTS), new_lints.1.get_groups_for(linter).unwrap_or(&EMPTY_GROUPS), ); for diff in diff(old_lints, new_lints, new_groups) { #[expect(clippy::print_stdout, reason = "printing out actual output")] match diff { Diff::Added { name, new } => { _ = serde::Serialize::serialize( &new, toml::ser::ValueSerializer::new(&mut value), )?; println!("+ {name} = {value}"); } Diff::Removed { name, old } => { _ = serde::Serialize::serialize( &old, toml::ser::ValueSerializer::new(&mut value), )?; println!("- {name} = {value}"); } Diff::Modified { name, old, new } => { if !args.ignore_level() { _ = serde::Serialize::serialize( &old, toml::ser::ValueSerializer::new(&mut value), )?; print!("~ {name} = {value}"); value.clear(); _ = serde::Serialize::serialize( &new, toml::ser::ValueSerializer::new(&mut value), )?; println!(" => {value}"); } } } value.clear(); } } } } Ok(()) }