#![doc = include_str!("../../Config.md")]
pub mod env;
pub mod toml;
pub use schemars::schema_for;
pub use schemars::Schema;
pub use summer_macros::Configurable;
use crate::error::Result;
use serde_json::json;
use std::{ops::Deref, sync::Arc};
pub trait Configurable {
fn config_prefix() -> &'static str;
}
pub trait ConfigRegistry {
fn get_config<T>(&self) -> Result<T>
where
T: serde::de::DeserializeOwned + Configurable;
}
#[derive(Debug, Clone)]
pub struct ConfigRef<T: Configurable>(Arc<T>);
impl<T: Configurable> ConfigRef<T> {
pub fn new(config: T) -> Self {
Self(Arc::new(config))
}
}
impl<T> Deref for ConfigRef<T>
where
T: Configurable,
{
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
pub struct ConfigSchema {
pub prefix: &'static str,
pub schema: fn() -> Schema,
}
inventory::collect!(ConfigSchema);
#[macro_export]
macro_rules! submit_config_schema {
($prefix:expr, $ty:ty) => {
::summer::submit_inventory! {
::summer::config::ConfigSchema {
prefix: $prefix,
schema: || ::summer::config::schema_for!($ty),
}
}
};
}
pub fn auto_config_schemas() -> Vec<(String, Schema)> {
inventory::iter::<ConfigSchema>
.into_iter()
.map(|c| (c.prefix.to_string(), (c.schema)()))
.collect()
}
pub fn merge_all_schemas() -> serde_json::Value {
let mut properties = serde_json::Map::new();
for (prefix, schema) in auto_config_schemas() {
properties.insert(prefix, serde_json::to_value(schema).unwrap());
}
json!({
"type": "object",
"properties": properties
})
}
pub fn write_merged_schema_to_file(path: &str) -> std::io::Result<()> {
let merged = merge_all_schemas();
std::fs::write(path, serde_json::to_string_pretty(&merged).unwrap())
}