58 lines
1.6 KiB
Rust
58 lines
1.6 KiB
Rust
use anyhow::Context;
|
|
use serde::de::DeserializeOwned;
|
|
use std::fs;
|
|
use std::path::Path;
|
|
|
|
pub fn load_toml_config<T>(path: &Path) -> anyhow::Result<T>
|
|
where
|
|
T: DeserializeOwned + Default,
|
|
{
|
|
if !path.exists() {
|
|
return Ok(T::default());
|
|
}
|
|
|
|
let contents = fs::read_to_string(path)
|
|
.with_context(|| format!("failed to read config file {}", path.display()))?;
|
|
toml::from_str(&contents)
|
|
.with_context(|| format!("failed to parse config file {}", path.display()))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::load_toml_config;
|
|
use serde::Deserialize;
|
|
use std::fs;
|
|
use std::path::PathBuf;
|
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
|
|
#[derive(Debug, Default, Deserialize, PartialEq)]
|
|
struct TestConfig {
|
|
value: String,
|
|
}
|
|
|
|
fn temp_path(name: &str) -> PathBuf {
|
|
let nanos = SystemTime::now()
|
|
.duration_since(UNIX_EPOCH)
|
|
.unwrap()
|
|
.as_nanos();
|
|
std::env::temp_dir().join(format!("{}-{}-{}.toml", name, std::process::id(), nanos))
|
|
}
|
|
|
|
#[test]
|
|
fn returns_default_when_file_is_missing() {
|
|
let path = temp_path("photon-config-missing");
|
|
let config: TestConfig = load_toml_config(&path).unwrap();
|
|
assert_eq!(config, TestConfig::default());
|
|
}
|
|
|
|
#[test]
|
|
fn loads_existing_toml_file() {
|
|
let path = temp_path("photon-config-load");
|
|
fs::write(&path, "value = \"hello\"\n").unwrap();
|
|
|
|
let config: TestConfig = load_toml_config(&path).unwrap();
|
|
assert_eq!(config.value, "hello");
|
|
|
|
let _ = fs::remove_file(path);
|
|
}
|
|
}
|