1use serde::{Deserialize, Serialize};
2use std::path::{Path, PathBuf};
3
4#[derive(Debug, Serialize, Deserialize, Clone)]
5pub struct Config {
6 pub rules: RuleConfig,
7 pub style: StyleConfig,
8 pub complexity: ComplexityConfig,
9 pub cache: CacheConfig,
10 pub autofix: AutoFixConfig,
11 pub performance: PerformanceConfig,
12 pub ignore: Vec<String>,
13}
14
15#[derive(Debug, Serialize, Deserialize, Clone)]
16pub struct RuleConfig {
17 pub check_syntax: bool,
18 pub check_style: bool,
19 pub check_naming: bool,
20 pub check_imports: bool,
21 pub check_unsafe: bool,
22 pub check_complexity: bool,
23 pub check_missing_docs: bool,
24 pub check_line_length: bool,
25 pub check_unwrap_usage: bool,
26 pub check_todo_macros: bool,
27 pub check_must_use: bool,
28 pub check_anti_patterns: bool,
29}
30
31#[derive(Debug, Serialize, Deserialize, Clone)]
32pub struct StyleConfig {
33 pub max_line_length: usize,
34 pub indent_size: usize,
35}
36
37#[derive(Debug, Serialize, Deserialize, Clone)]
38pub struct ComplexityConfig {
39 pub max_cyclomatic: usize,
40 pub max_cognitive: usize,
41 pub max_nesting: usize,
42}
43
44#[derive(Debug, Serialize, Deserialize, Clone)]
45pub struct CacheConfig {
46 pub enabled: bool,
47 pub cache_dir: Option<PathBuf>,
48 pub ast_cache_enabled: bool,
49 pub max_cache_size: usize,
50 pub cache_ttl_hours: u64,
51}
52
53#[derive(Debug, Serialize, Deserialize, Clone)]
54pub struct AutoFixConfig {
55 pub enabled: bool,
56 pub organize_imports: bool,
57 pub fix_naming_conventions: bool,
58 pub add_missing_docs: bool,
59 pub apply_safe_fixes_only: bool,
60 pub max_fixes_per_file: usize,
61}
62
63#[derive(Debug, Serialize, Deserialize, Clone)]
64pub struct PerformanceConfig {
65 pub incremental_analysis: bool,
66 pub parallel_analysis: bool,
67 pub memory_mapped_io: bool,
68 pub large_file_threshold: usize,
69 pub max_threads: Option<usize>,
70}
71
72impl Default for Config {
73 fn default() -> Self {
74 Self {
75 rules: RuleConfig {
76 check_syntax: true,
77 check_style: true,
78 check_naming: true,
79 check_imports: true,
80 check_unsafe: true,
81 check_complexity: true,
82 check_missing_docs: true,
83 check_line_length: true,
84 check_unwrap_usage: true,
85 check_todo_macros: true,
86 check_must_use: true,
87 check_anti_patterns: true,
88 },
89 style: StyleConfig {
90 max_line_length: 100,
91 indent_size: 4,
92 },
93 complexity: ComplexityConfig {
94 max_cyclomatic: 10,
95 max_cognitive: 15,
96 max_nesting: 5,
97 },
98 cache: CacheConfig {
99 enabled: true,
100 cache_dir: None, ast_cache_enabled: true,
102 max_cache_size: 10000,
103 cache_ttl_hours: 24,
104 },
105 autofix: AutoFixConfig {
106 enabled: true,
107 organize_imports: true,
108 fix_naming_conventions: true,
109 add_missing_docs: false, apply_safe_fixes_only: true,
111 max_fixes_per_file: 100,
112 },
113 performance: PerformanceConfig {
114 incremental_analysis: true,
115 parallel_analysis: true,
116 memory_mapped_io: true,
117 large_file_threshold: 1024 * 1024, max_threads: None, },
120 ignore: vec![
121 "target/**".to_string(),
122 ".git/**".to_string(),
123 "node_modules/**".to_string(),
124 ],
125 }
126 }
127}
128
129impl Config {
130 pub fn load_or_default(path: &Path) -> Self {
131 let config_path = path.join(".fl.toml");
132 if config_path.exists() {
133 if let Ok(content) = std::fs::read_to_string(&config_path) {
134 if let Ok(config) = toml::from_str(&content) {
135 return config;
136 }
137 }
138 }
139 Self::default()
140 }
141}
142
143pub struct ConfigManager;
144
145impl ConfigManager {
146 pub fn new() -> Self {
147 Self
148 }
149
150 pub fn create_default_config(&self) -> std::io::Result<()> {
151 let config = Config::default();
152 let toml = toml::to_string_pretty(&config).unwrap();
153 std::fs::write(".fl.toml", toml)
154 }
155}