cc_audit/config/
loading.rs1use std::fs;
4use std::path::Path;
5
6use super::error::ConfigError;
7use super::types::Config;
8
9impl Config {
10 pub fn from_file(path: &Path) -> Result<Self, ConfigError> {
12 let content = fs::read_to_string(path).map_err(|e| ConfigError::ReadFile {
13 path: path.display().to_string(),
14 source: e,
15 })?;
16
17 let ext = path
18 .extension()
19 .and_then(|e| e.to_str())
20 .unwrap_or("")
21 .to_lowercase();
22
23 match ext.as_str() {
24 "yaml" | "yml" => serde_yaml::from_str(&content).map_err(|e| ConfigError::ParseYaml {
25 path: path.display().to_string(),
26 source: e,
27 }),
28 "json" => serde_json::from_str(&content).map_err(|e| ConfigError::ParseJson {
29 path: path.display().to_string(),
30 source: e,
31 }),
32 "toml" => toml::from_str(&content).map_err(|e| ConfigError::ParseToml {
33 path: path.display().to_string(),
34 source: e,
35 }),
36 _ => Err(ConfigError::UnsupportedFormat(
37 path.display().to_string(),
38 ext,
39 )),
40 }
41 }
42
43 pub fn load(project_root: Option<&Path>) -> Self {
52 if let Some(root) = project_root {
54 for filename in &[
55 ".cc-audit.yaml",
56 ".cc-audit.yml",
57 ".cc-audit.json",
58 ".cc-audit.toml",
59 ] {
60 let path = root.join(filename);
61 if path.exists()
62 && let Ok(config) = Self::from_file(&path)
63 {
64 return config;
65 }
66 }
67 }
68
69 if let Some(config_dir) = dirs::config_dir() {
71 let global_config = config_dir.join("cc-audit").join("config.yaml");
72 if global_config.exists()
73 && let Ok(config) = Self::from_file(&global_config)
74 {
75 return config;
76 }
77 }
78
79 Self::default()
81 }
82}