1use doido_core::Environment;
9use serde::Deserialize;
10
11pub use doido_core::logger::LoggerConfig;
15
16#[derive(Debug, Clone, Deserialize)]
18pub struct DatabaseConfig {
19 pub url: String,
22 #[serde(default)]
24 pub pool: Option<u32>,
25 #[serde(default)]
27 pub connect_timeout: Option<u64>,
28}
29
30impl Default for DatabaseConfig {
31 fn default() -> Self {
32 Self {
33 url: "sqlite://db/development.db".to_string(),
34 pool: None,
35 connect_timeout: None,
36 }
37 }
38}
39
40pub trait Config: Send + Sync {
43 fn database(&self) -> &DatabaseConfig;
45 fn logger(&self) -> &LoggerConfig;
47}
48
49#[derive(Debug, Clone, Default, Deserialize)]
52pub struct YamlConfig {
53 #[serde(default)]
54 pub database: DatabaseConfig,
55 #[serde(default)]
56 pub logger: LoggerConfig,
57}
58
59impl Config for YamlConfig {
60 fn database(&self) -> &DatabaseConfig {
61 &self.database
62 }
63
64 fn logger(&self) -> &LoggerConfig {
65 &self.logger
66 }
67}
68
69impl YamlConfig {
70 pub fn load() -> std::io::Result<Self> {
72 Self::load_env(Environment::get_env())
73 }
74
75 pub fn load_env(env: Environment) -> std::io::Result<Self> {
77 let path = format!("config/{}.yml", env.as_str());
78 let contents = std::fs::read_to_string(&path)?;
79 Self::from_yaml(&contents)
80 }
81
82 pub fn from_yaml(yaml: &str) -> std::io::Result<Self> {
84 serde_norway::from_str(yaml)
85 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
86 }
87}
88
89pub fn load() -> Box<dyn Config> {
92 Box::new(YamlConfig::load().unwrap_or_default())
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn parses_database_url_and_ignores_other_sections() {
101 let yaml = "server:\n bind: 0.0.0.0\n port: 3000\ndatabase:\n url: postgres://localhost/app_development\n";
102 let config = YamlConfig::from_yaml(yaml).unwrap();
103 assert_eq!(
104 config.database().url,
105 "postgres://localhost/app_development"
106 );
107 }
108
109 #[test]
110 fn defaults_when_database_section_absent() {
111 let config = YamlConfig::from_yaml("server:\n port: 3000\n").unwrap();
112 assert_eq!(config.database().url, "sqlite://db/development.db");
113 }
114}