Skip to main content

claude_native/
config.rs

1use std::collections::HashSet;
2use std::path::Path;
3
4use serde::Deserialize;
5
6/// User configuration from .claude-native.yml
7#[derive(Debug, Default, Deserialize)]
8pub struct Config {
9    /// Rules to disable by ID (e.g., ["4.7", "μ2"])
10    #[serde(default)]
11    pub disabled_rules: Vec<String>,
12
13    /// Override the auto-detected project type
14    #[serde(default)]
15    pub project_type: Option<String>,
16
17    /// Custom thresholds
18    #[serde(default)]
19    pub thresholds: Thresholds,
20}
21
22#[derive(Debug, Deserialize)]
23pub struct Thresholds {
24    /// Max lines per file before warning (default: 300) and error (default: 500)
25    #[serde(default = "default_file_warn")]
26    pub file_lines_warn: usize,
27    #[serde(default = "default_file_error")]
28    pub file_lines_error: usize,
29
30    /// Max lines per function before warning (default: 50) and error (default: 80)
31    #[serde(default = "default_fn_warn")]
32    pub function_lines_warn: usize,
33    #[serde(default = "default_fn_error")]
34    pub function_lines_error: usize,
35
36    /// Max lines for CLAUDE.md (default: 200)
37    #[serde(default = "default_claude_md_max")]
38    pub claude_md_max_lines: usize,
39}
40
41fn default_file_warn() -> usize { 300 }
42fn default_file_error() -> usize { 500 }
43fn default_fn_warn() -> usize { 50 }
44fn default_fn_error() -> usize { 80 }
45fn default_claude_md_max() -> usize { 200 }
46
47impl Default for Thresholds {
48    fn default() -> Self {
49        Self {
50            file_lines_warn: 300,
51            file_lines_error: 500,
52            function_lines_warn: 50,
53            function_lines_error: 80,
54            claude_md_max_lines: 200,
55        }
56    }
57}
58
59impl Config {
60    /// Load config from .claude-native.yml in the project root.
61    /// Returns default config if file doesn't exist.
62    pub fn load(root: &Path) -> Self {
63        let path = root.join(".claude-native.yml");
64        if !path.exists() {
65            return Self::default();
66        }
67        match std::fs::read_to_string(&path) {
68            Ok(content) => serde_yaml::from_str(&content).unwrap_or_default(),
69            Err(_) => Self::default(),
70        }
71    }
72
73    pub fn is_rule_disabled(&self, rule_id: &str) -> bool {
74        self.disabled_rules.iter().any(|r| r == rule_id)
75    }
76
77    pub fn disabled_set(&self) -> HashSet<String> {
78        self.disabled_rules.iter().cloned().collect()
79    }
80}