ferrous_forge/standards/
implementation.rs1use super::types::*;
4use crate::Result;
5
6impl CodingStandards {
7 pub fn load() -> Result<Self> {
9 Ok(Self::default())
12 }
13
14 pub fn save(&self) -> Result<()> {
16 Ok(())
18 }
19
20 pub fn get_clippy_rules(&self) -> Vec<String> {
22 let mut rules = vec!["-D warnings".to_string()];
23
24 if self.banned_patterns.ban_unwrap {
25 rules.push("-D clippy::unwrap_used".to_string());
26 }
27
28 if self.banned_patterns.ban_expect {
29 rules.push("-D clippy::expect_used".to_string());
30 }
31
32 if self.banned_patterns.ban_panic {
33 rules.push("-D clippy::panic".to_string());
34 }
35
36 if self.banned_patterns.ban_todo {
37 rules.push("-D clippy::todo".to_string());
38 }
39
40 if self.banned_patterns.ban_unimplemented {
41 rules.push("-D clippy::unimplemented".to_string());
42 }
43
44 if self.documentation.require_public_docs {
45 rules.push("-D missing_docs".to_string());
46 }
47
48 if self.security.ban_unsafe {
49 rules.push("-F unsafe_code".to_string());
50 }
51
52 rules.extend([
54 "-W clippy::pedantic".to_string(),
55 "-W clippy::nursery".to_string(),
56 "-W clippy::cargo".to_string(),
57 "-D clippy::dbg_macro".to_string(),
58 "-D clippy::print_stdout".to_string(),
59 "-D clippy::print_stderr".to_string(),
60 ]);
61
62 rules
63 }
64
65 pub fn generate_clippy_config(&self) -> String {
67 format!(
68 r#"# Ferrous Forge - Rust Standards Enforcement
69# Generated automatically - do not edit manually
70
71msrv = "{}"
72max-fn-params-bools = 2
73max-struct-bools = 2
74max-trait-bounds = 2
75max-include-file-size = {}
76min-ident-chars-threshold = 2
77literal-representation-threshold = 1000
78check-private-items = {}
79missing-docs-allow-unused = false
80allow-comparison-to-zero = false
81allow-mixed-uninlined-format-args = false
82allow-one-hash-in-raw-strings = false
83allow-useless-vec-in-tests = false
84allow-indexing-slicing-in-tests = false
85allowed-idents-below-min-chars = ["i", "j", "x", "y", "z"]
86allowed-wildcard-imports = []
87allow-exact-repetitions = false
88allow-private-module-inception = false
89too-large-for-stack = 100
90upper-case-acronyms-aggressive = true
91allowed-scripts = ["Latin"]
92disallowed-names = ["foo", "bar", "baz", "qux", "quux", "test", "tmp", "temp"]
93unreadable-literal-lint-fractions = true
94semicolon-inside-block-ignore-singleline = false
95semicolon-outside-block-ignore-multiline = false
96arithmetic-side-effects-allowed = []
97"#,
98 self.edition.min_rust_version,
99 self.file_limits.max_lines * 1000, self.documentation.require_private_docs,
101 )
102 }
103
104 pub async fn check_compliance(&self, project_path: &std::path::Path) -> Result<Vec<String>> {
106 let mut violations = Vec::new();
107
108 let cargo_toml = project_path.join("Cargo.toml");
110 if cargo_toml.exists() {
111 let content = tokio::fs::read_to_string(&cargo_toml).await?;
112 if !content.contains(&format!(r#"edition = "{}""#, self.edition.required_edition)) {
113 violations.push(format!(
114 "Project must use Rust Edition {}",
115 self.edition.required_edition
116 ));
117 }
118 }
119
120 Ok(violations)
123 }
124}