Skip to main content

xchecker_config/config/
sources.rs

1use std::collections::HashMap;
2
3use super::Config;
4use xchecker_utils::types::ConfigSource;
5
6fn stable_source_label(source: &ConfigSource) -> &'static str {
7    match source {
8        ConfigSource::Cli => "cli",
9        ConfigSource::Env => "env",
10        ConfigSource::Config => "config",
11        ConfigSource::Programmatic => "programmatic",
12        ConfigSource::Default => "default",
13    }
14}
15
16fn source_label(source: Option<&ConfigSource>) -> String {
17    match source {
18        Some(src) => stable_source_label(src).to_string(),
19        None => stable_source_label(&ConfigSource::Default).to_string(),
20    }
21}
22
23impl Config {
24    /// Get effective configuration as key-value pairs with source attribution
25    #[must_use]
26    pub fn effective_config(&self) -> HashMap<String, (String, String)> {
27        let mut config = HashMap::new();
28
29        // Helper to add config value with source
30        let mut add_config = |key: &str, value: Option<&str>| {
31            if let Some(val) = value {
32                let source = source_label(self.source_attribution.get(key));
33                config.insert(key.to_string(), (val.to_string(), source));
34            }
35        };
36
37        // Add all configuration values
38        add_config("model", self.defaults.model.as_deref());
39
40        if let Some(max_turns) = self.defaults.max_turns {
41            add_config("max_turns", Some(&max_turns.to_string()));
42        }
43
44        if let Some(packet_max_bytes) = self.defaults.packet_max_bytes {
45            add_config("packet_max_bytes", Some(&packet_max_bytes.to_string()));
46        }
47
48        if let Some(packet_max_lines) = self.defaults.packet_max_lines {
49            add_config("packet_max_lines", Some(&packet_max_lines.to_string()));
50        }
51
52        add_config("output_format", self.defaults.output_format.as_deref());
53
54        if let Some(verbose) = self.defaults.verbose {
55            add_config("verbose", Some(&verbose.to_string()));
56        }
57
58        add_config("runner_mode", self.runner.mode.as_deref());
59        add_config("runner_distro", self.runner.distro.as_deref());
60        add_config("claude_path", self.runner.claude_path.as_deref());
61        add_config("llm_provider", self.llm.provider.as_deref());
62        add_config(
63            "llm_fallback_provider",
64            self.llm.fallback_provider.as_deref(),
65        );
66        add_config("execution_strategy", self.llm.execution_strategy.as_deref());
67        add_config("prompt_template", self.llm.prompt_template.as_deref());
68
69        // Add selector information
70        let include_patterns = self.selectors.include.join(", ");
71        let exclude_patterns = self.selectors.exclude.join(", ");
72
73        let include_source = source_label(self.source_attribution.get("selectors_include"));
74        let exclude_source = source_label(self.source_attribution.get("selectors_exclude"));
75
76        config.insert(
77            "selectors_include".to_string(),
78            (include_patterns, include_source),
79        );
80        config.insert(
81            "selectors_exclude".to_string(),
82            (exclude_patterns, exclude_source),
83        );
84
85        config
86    }
87}