extern crate proc_macro;
#[macro_use]
extern crate quote;
extern crate syn;
use proc_macro::TokenStream;
use darling::FromMeta;
use syn::parse_macro_input;
#[derive(Debug, FromMeta)]
struct Args {
key: String,
}
#[proc_macro_attribute]
pub fn settings(metadata: TokenStream, input: TokenStream) -> TokenStream {
let input_struct = parse_macro_input!(input as syn::ItemStruct);
let attr_args = parse_macro_input!(metadata as syn::AttributeArgs);
let args = Args::from_list(&attr_args).unwrap();
let struct_ident = input_struct.ident.clone();
let key = args.key.clone();
let uppercase_key = key.to_uppercase();
TokenStream::from(quote! {
#[derive(Debug, Clone, ::lazy_settings::serde::Deserialize, ::lazy_settings::getset_scoped::Getters)]
#[get]
#input_struct
impl #struct_ident {
pub fn get(instance_name: &str) -> Result<Self, ::lazy_settings::eyre::Report> {
static SINGLETON: ::lazy_settings::once_cell::sync::Lazy<::lazy_settings::parking_lot::RwLock<::std::collections::HashMap<String, #struct_ident>>> = ::once_cell::sync::Lazy::new(|| ::lazy_settings::parking_lot::RwLock::new(::std::collections::HashMap::default()));
{
let singleton_ro = SINGLETON.read();
if let Some(existing_settings) = singleton_ro.get(instance_name) {
return Ok(existing_settings.clone())
}
}
{
let new_settings = ::lazy_settings::config::Config::builder()
.add_source(::lazy_settings::config::Environment::with_prefix(
format!("APP_{}_{}", #uppercase_key, instance_name.to_uppercase()).as_str(),
))
.build()?;
eprintln!("Initializing {} settings, instance name: {}", #key, instance_name);
let new_settings: #struct_ident = ::lazy_settings::eyre::WrapErr::wrap_err(new_settings.try_deserialize(), "Cannot read settings.")?;
let mut singleton_rw = SINGLETON.write();
singleton_rw.insert(instance_name.to_string(), new_settings.clone());
return Ok(new_settings)
}
}
}
})
}