#![forbid(unsafe_code)]
#![deny(missing_docs)]
mod args;
mod expand;
use proc_macro::TokenStream;
use syn::ItemStruct;
#[proc_macro_attribute]
pub fn dynamic_config(attr: TokenStream, item: TokenStream) -> TokenStream {
let fallback = item.clone();
let with_original = |error: syn::Error| -> TokenStream {
let mut output: TokenStream = error.into_compile_error().into();
output.extend(fallback.clone());
output
};
let input: ItemStruct = match syn::parse(item.clone()) {
Ok(input) => input,
Err(_) => {
return with_original(syn::Error::new_spanned(
proc_macro2::TokenStream::from(item),
"#[dynamic_config] goes on a struct with named fields — the \
fields are what the configuration deserializes into; an enum \
or function has nowhere to put them",
))
}
};
if let Err(error) = syn::parse::<args::Args>(attr) {
return with_original(error);
}
match expand::expand(input) {
Ok(tokens) => tokens.into(),
Err(error) => with_original(error),
}
}