lazy_settings_macros/
lib.rs1extern crate proc_macro;
2#[macro_use]
3extern crate quote;
4extern crate syn;
5
6use proc_macro::TokenStream;
7
8use darling::FromMeta;
9use syn::parse_macro_input;
10
11#[derive(Debug, FromMeta)]
12struct Args {
13 key: String,
14}
15
16#[proc_macro_attribute]
17pub fn settings(metadata: TokenStream, input: TokenStream) -> TokenStream {
18 let input_struct = parse_macro_input!(input as syn::ItemStruct);
19 let attr_args = parse_macro_input!(metadata as syn::AttributeArgs);
20 let args = Args::from_list(&attr_args).unwrap();
21 let struct_ident = input_struct.ident.clone();
22 let key = args.key.clone();
23 let uppercase_key = key.to_uppercase();
24 TokenStream::from(quote! {
25 #[derive(Debug, Clone, ::lazy_settings::serde::Deserialize, ::lazy_settings::getset_scoped::Getters)]
26 #[get]
27 #input_struct
28
29 impl #struct_ident {
30 pub fn get(instance_name: &str) -> Result<Self, ::lazy_settings::eyre::Report> {
31 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()));
32 {
33 let singleton_ro = SINGLETON.read();
34 if let Some(existing_settings) = singleton_ro.get(instance_name) {
35 return Ok(existing_settings.clone())
36 }
37 }
38 {
39 let new_settings = ::lazy_settings::config::Config::builder()
40 .add_source(::lazy_settings::config::Environment::with_prefix(
41 format!("APP_{}_{}", #uppercase_key, instance_name.to_uppercase()).as_str(),
42 ))
43 .build()?;
44 eprintln!("Initializing {} settings, instance name: {}", #key, instance_name);
45 let new_settings: #struct_ident = ::lazy_settings::eyre::WrapErr::wrap_err(new_settings.try_deserialize(), "Cannot read settings.")?;
46 let mut singleton_rw = SINGLETON.write();
47 singleton_rw.insert(instance_name.to_string(), new_settings.clone());
48 return Ok(new_settings)
49 }
50 }
51 }
52 })
53}