Skip to main content

run/
config.rs

1use std::path::{Path, PathBuf};
2
3use serde::Deserialize;
4
5/// Project-level configuration loaded from `run.toml` or `.runrc`.
6#[derive(Debug, Default, Deserialize)]
7#[serde(default)]
8pub struct RunConfig {
9    /// Default language when none is specified.
10    pub language: Option<String>,
11    /// Execution timeout in seconds.
12    pub timeout: Option<u64>,
13    /// Always show execution timing.
14    pub timing: Option<bool>,
15    /// Default benchmark iterations.
16    pub bench_iterations: Option<u32>,
17}
18
19impl RunConfig {
20    /// Search for a config file in the current directory and ancestors.
21    /// Checks `run.toml`, then `.runrc` (TOML format).
22    pub fn discover() -> Self {
23        let cwd = std::env::current_dir().ok();
24        let cwd = match cwd {
25            Some(ref p) => p.as_path(),
26            None => return Self::default(),
27        };
28
29        for dir in cwd.ancestors() {
30            for name in &["run.toml", ".runrc"] {
31                let candidate = dir.join(name);
32                if candidate.is_file()
33                    && let Ok(config) = Self::load(&candidate)
34                {
35                    return config;
36                }
37            }
38        }
39
40        Self::default()
41    }
42
43    pub fn load(path: &Path) -> Result<Self, String> {
44        let content = std::fs::read_to_string(path)
45            .map_err(|e| format!("failed to read {}: {e}", path.display()))?;
46        toml::from_str(&content).map_err(|e| format!("invalid config in {}: {e}", path.display()))
47    }
48
49    pub fn apply_env(&self) {
50        crate::runtime::apply_config_defaults(self.timeout, self.timing);
51    }
52
53    pub fn find_config_path() -> Option<PathBuf> {
54        let cwd = std::env::current_dir().ok()?;
55        for dir in cwd.ancestors() {
56            for name in &["run.toml", ".runrc"] {
57                let candidate = dir.join(name);
58                if candidate.is_file() {
59                    return Some(candidate);
60                }
61            }
62        }
63        None
64    }
65}