road_runner_common/
config.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4pub struct ServiceConfig {
5 pub service_name: String,
6 pub log_level: String, pub log_format: String, pub max_page_size: u32,
9}
10
11impl Default for ServiceConfig {
12 fn default() -> Self {
13 Self {
14 service_name: "my-service".to_string(),
15 log_level: "info".to_string(),
16 log_format: "json".to_string(),
17 max_page_size: 100,
18 }
19 }
20}
21
22impl ServiceConfig {
23 pub fn from_env_fallback() -> Self {
24 let mut cfg = Self::default();
25
26 if let Ok(v) = std::env::var("SERVICE_NAME") {
27 cfg.service_name = v;
28 }
29 if let Ok(v) = std::env::var("LOG_LEVEL") {
30 cfg.log_level = v;
31 }
32 if let Ok(v) = std::env::var("LOG_FORMAT") {
33 cfg.log_format = v;
34 }
35 if let Ok(v) = std::env::var("MAX_PAGE_SIZE") {
36 if let Ok(n) = v.parse::<u32>() {
37 cfg.max_page_size = n.max(1);
38 }
39 }
40 cfg
41 }
42
43 #[cfg(feature = "config")]
44 pub fn load() -> anyhow::Result<Self> {
45 let _ = dotenvy::dotenv();
46
47 let config_file = std::env::var("CONFIG_FILE").ok();
48
49 let mut builder = config::Config::builder();
50
51 if let Some(path) = config_file {
52 builder = builder.add_source(config::File::with_name(&path).required(false));
53 }
54
55 builder = builder.add_source(config::Environment::default());
56
57 let cfg = builder.build()?;
58 Ok(cfg.try_deserialize()?)
59 }
60}