76 lines
2.1 KiB
Rust
76 lines
2.1 KiB
Rust
use figment::{
|
|
providers::{Format, Json, Yaml},
|
|
Figment,
|
|
};
|
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
|
|
|
use crate::{
|
|
auth::AppAuthConfig, dal::config::AppDalConfig, extract::mikan::AppMikanConfig,
|
|
graphql::config::AppGraphQLConfig,
|
|
};
|
|
|
|
const DEFAULT_APP_SETTINGS_MIXIN: &str = include_str!("./settings_mixin.yaml");
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct AppConfig {
|
|
pub auth: AppAuthConfig,
|
|
pub dal: AppDalConfig,
|
|
pub mikan: AppMikanConfig,
|
|
pub graphql: AppGraphQLConfig,
|
|
}
|
|
|
|
pub fn deserialize_key_path_from_json_value<T: DeserializeOwned>(
|
|
value: &serde_json::Value,
|
|
key_path: &[&str],
|
|
) -> Result<Option<T>, loco_rs::Error> {
|
|
let mut stack = vec![("", value)];
|
|
for key in key_path {
|
|
let current = stack.last().unwrap().1;
|
|
if let Some(v) = current.get(key) {
|
|
stack.push((key, v));
|
|
} else {
|
|
return Ok(None);
|
|
}
|
|
}
|
|
let result: T = serde_json::from_value(stack.pop().unwrap().1.clone())?;
|
|
Ok(Some(result))
|
|
}
|
|
|
|
pub fn deserialize_key_path_from_app_config<T: DeserializeOwned>(
|
|
app_config: &loco_rs::config::Config,
|
|
key_path: &[&str],
|
|
) -> Result<Option<T>, loco_rs::Error> {
|
|
let settings = app_config.settings.as_ref();
|
|
if let Some(settings) = settings {
|
|
deserialize_key_path_from_json_value(settings, key_path)
|
|
} else {
|
|
Ok(None)
|
|
}
|
|
}
|
|
|
|
pub trait AppConfigExt {
|
|
fn get_root_conf(&self) -> &loco_rs::config::Config;
|
|
|
|
fn get_app_conf(&self) -> loco_rs::Result<AppConfig> {
|
|
let settings_str = self
|
|
.get_root_conf()
|
|
.settings
|
|
.as_ref()
|
|
.map(serde_json::to_string)
|
|
.unwrap_or_else(|| Ok(String::new()))?;
|
|
|
|
let app_config = Figment::from(Json::string(&settings_str))
|
|
.merge(Yaml::string(DEFAULT_APP_SETTINGS_MIXIN))
|
|
.extract()
|
|
.map_err(loco_rs::Error::wrap)?;
|
|
|
|
Ok(app_config)
|
|
}
|
|
}
|
|
|
|
impl AppConfigExt for loco_rs::config::Config {
|
|
fn get_root_conf(&self) -> &loco_rs::config::Config {
|
|
self
|
|
}
|
|
}
|