use std::collections::HashSet;
use std::path::Path;
use serde::Deserialize;
#[derive(Debug, Default, Deserialize)]
pub struct Config {
#[serde(default)]
pub disabled_rules: Vec<String>,
#[serde(default)]
pub project_type: Option<String>,
#[serde(default)]
pub thresholds: Thresholds,
}
#[derive(Debug, Deserialize)]
pub struct Thresholds {
#[serde(default = "default_file_warn")]
pub file_lines_warn: usize,
#[serde(default = "default_file_error")]
pub file_lines_error: usize,
#[serde(default = "default_fn_warn")]
pub function_lines_warn: usize,
#[serde(default = "default_fn_error")]
pub function_lines_error: usize,
#[serde(default = "default_claude_md_max")]
pub claude_md_max_lines: usize,
}
fn default_file_warn() -> usize { 300 }
fn default_file_error() -> usize { 500 }
fn default_fn_warn() -> usize { 50 }
fn default_fn_error() -> usize { 80 }
fn default_claude_md_max() -> usize { 200 }
impl Default for Thresholds {
fn default() -> Self {
Self {
file_lines_warn: 300,
file_lines_error: 500,
function_lines_warn: 50,
function_lines_error: 80,
claude_md_max_lines: 200,
}
}
}
impl Config {
pub fn load(root: &Path) -> Self {
let path = root.join(".claude-native.yml");
if !path.exists() {
return Self::default();
}
match std::fs::read_to_string(&path) {
Ok(content) => serde_yaml::from_str(&content).unwrap_or_default(),
Err(_) => Self::default(),
}
}
pub fn is_rule_disabled(&self, rule_id: &str) -> bool {
self.disabled_rules.iter().any(|r| r == rule_id)
}
pub fn disabled_set(&self) -> HashSet<String> {
self.disabled_rules.iter().cloned().collect()
}
}