use proc_macro::TokenStream;
use quote::quote;
use syn::{parse::Parser, Attribute, Data, DeriveInput, Error, Fields};
pub(crate) fn merge_conf(input: TokenStream) -> Result<TokenStream, Error> {
let mut input: DeriveInput = syn::parse(input)?;
let attributes = quote!(
#[derive(::std::fmt::Debug, ::std::default::Default, ::serde::Deserialize)]
#[serde(default)]
);
let attributes = Attribute::parse_outer.parse2(attributes)?;
input.attrs.extend(attributes);
match &mut input.data {
Data::Struct(struct_) => {
if let Fields::Named(fields) = &mut struct_.fields {
for field in fields.named.iter_mut() {
let attributes = quote!(#[serde(flatten)]);
let attributes = Attribute::parse_outer.parse2(attributes)?;
field.attrs.extend(attributes)
}
} else {
return Err(Error::new_spanned(
&struct_.fields,
"merge_conf can only apply to named fields",
));
}
}
Data::Enum(enum_) => {
return Err(Error::new_spanned(
enum_.enum_token,
"merge_conf can only apply to struct",
));
}
Data::Union(union_) => {
return Err(Error::new_spanned(
union_.union_token,
"merge_conf can only apply to struct",
));
}
}
Ok(quote! {#input}.into())
}