movey_utils/
app_config.rs1use config::{Config, Environment};
2use std::ops::Deref;
3use std::sync::RwLock;
4use lazy_static::lazy_static;
5use serde::Deserialize;
6
7use super::error::Result;
8
9lazy_static! {
12 static ref CONFIG: RwLock<Config> = RwLock::new(Config::new());
13}
14
15#[derive(Debug, Deserialize)]
16pub struct Database {
17 pub url: String,
18}
19
20#[derive(Debug, Deserialize)]
21pub struct AppConfig {
22 pub debug: bool,
23 pub database: Database,
24}
25
26impl AppConfig {
27 pub fn init(default_config: Option<&str>) -> Result<()> {
28 let mut settings = Config::new();
29
30 if let Some(config_contents) = default_config {
34 settings.merge(config::File::from_str(&config_contents, config::FileFormat::Toml))?;
36 }
37
38 settings.merge(Environment::with_prefix("APP"))?;
40
41 {
45 let mut w = CONFIG.write()?;
46 *w = settings;
47 }
48
49 Ok(())
50 }
51
52 pub fn merge_config(config_file: Option<&str>) -> Result<()> {
53 if let Some(config_file_path) = config_file {
55 {
56 CONFIG
57 .write()?
58 .merge(config::File::with_name(config_file_path))?;
59 }
60 }
61 Ok(())
62 }
63
64 pub fn set(key: &str, value: &str) -> Result<()> {
66 {
67 CONFIG.write()?.set(key, value)?;
69 }
70
71 Ok(())
72 }
73
74 pub fn get<'de, T>(key: &'de str) -> Result<T>
76 where
77 T: serde::Deserialize<'de>,
78 {
79 Ok(CONFIG.read()?.get::<T>(key)?)
80 }
81
82 pub fn fetch() -> Result<AppConfig> {
86 let r = CONFIG.read()?;
88
89 let config_clone = r.deref().clone();
91
92 Ok(config_clone.try_into()?)
94 }
95}