1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Config {
8 pub models: ModelConfig,
10
11 #[serde(default = "default_artifact_dir")]
13 pub artifact_dir: String,
14}
15
16impl Default for Config {
17 fn default() -> Self {
18 Self {
19 models: ModelConfig::default(),
20 artifact_dir: default_artifact_dir(),
21 }
22 }
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize, Default)]
26pub struct ModelConfig {
27 pub analyzer: Option<String>,
29
30 pub judge: Option<String>,
32
33 pub default: Option<String>,
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40 use tempfile::tempdir;
41
42 #[test]
43 fn default_config_uses_standard_artifact_dir() {
44 assert_eq!(Config::default().artifact_dir, ".mdx-rust");
45 }
46
47 #[test]
48 fn missing_project_config_loads_usable_defaults() {
49 let dir = tempdir().unwrap();
50 let config = Config::load_from_project(dir.path()).unwrap();
51
52 assert_eq!(config.artifact_dir, ".mdx-rust");
53 }
54}
55
56fn default_artifact_dir() -> String {
57 ".mdx-rust".to_string()
58}
59
60impl Config {
61 pub fn load_from_project(root: &std::path::Path) -> anyhow::Result<Self> {
63 let config_path = root.join(".mdx-rust/config.toml");
64
65 if !config_path.exists() {
66 return Ok(Self::default());
67 }
68
69 let content = std::fs::read_to_string(config_path)?;
70 let mut cfg: Config = toml::from_str(&content)?;
71
72 if cfg.artifact_dir.is_empty() {
73 cfg.artifact_dir = default_artifact_dir();
74 }
75
76 Ok(cfg)
77 }
78}