#[cfg(feature = "config-macros")]
pub use rok_config_macros::Config;
#[cfg(feature = "config-macros")]
pub use rok_config_macros::RokConfig;
pub trait FromEnv: Sized {
fn from_env() -> Self;
}
pub trait Configurable: Sized + serde::de::DeserializeOwned + Send + Sync + 'static {
fn key() -> &'static str;
}
pub fn load_config<T: Configurable>() -> Option<T> {
let path = std::path::Path::new("config").join(format!("{}.toml", T::key()));
if path.exists() {
let content = std::fs::read_to_string(&path).ok()?;
if let Ok(cfg) = toml::from_str(&content) {
return Some(cfg);
}
}
None
}
pub fn discover_configs() -> Vec<(String, std::path::PathBuf)> {
let config_dir = std::path::Path::new("config");
if !config_dir.is_dir() {
return Vec::new();
}
let mut entries = Vec::new();
if let Ok(dir) = std::fs::read_dir(config_dir) {
for entry in dir.flatten() {
let path = entry.path();
if path.extension().and_then(|s| s.to_str()) == Some("toml") {
if let Some(stem) = path.file_stem().and_then(|s| s.to_str()).map(|s| s.to_string()) {
entries.push((stem, path));
}
}
}
}
entries
}
pub struct Config;
impl Config {
pub fn load<T: FromEnv>() -> T {
let _ = ::dotenvy::dotenv();
T::from_env()
}
}