Unify Settings and AllSettings (#7532)

This commit is contained in:
Micha Reiser 2023-09-20 15:56:07 +02:00 committed by GitHub
parent ca3c15858d
commit b19eec9b2a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 204 additions and 147 deletions

View file

@ -1,7 +1,8 @@
use proc_macro2::TokenStream;
use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote};
use syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;
use syn::{Data, DeriveInput, Error, Fields};
use syn::{Data, DeriveInput, Error, Field, Fields, Token};
pub(crate) fn derive_cache_key(item: &DeriveInput) -> syn::Result<TokenStream> {
let fields = match &item.data {
@ -65,7 +66,15 @@ pub(crate) fn derive_cache_key(item: &DeriveInput) -> syn::Result<TokenStream> {
}
Data::Struct(item_struct) => {
let fields = item_struct.fields.iter().enumerate().map(|(i, field)| {
let mut fields = Vec::with_capacity(item_struct.fields.len());
for (i, field) in item_struct.fields.iter().enumerate() {
if let Some(cache_field_attribute) = cache_key_field_attribute(field)? {
if cache_field_attribute.ignore {
continue;
}
}
let field_attr = match &field.ident {
Some(ident) => quote!(self.#ident),
None => {
@ -74,8 +83,8 @@ pub(crate) fn derive_cache_key(item: &DeriveInput) -> syn::Result<TokenStream> {
}
};
quote!(#field_attr.cache_key(key);)
});
fields.push(quote!(#field_attr.cache_key(key);));
}
quote! {#(#fields)*}
}
@ -101,3 +110,44 @@ pub(crate) fn derive_cache_key(item: &DeriveInput) -> syn::Result<TokenStream> {
}
))
}
fn cache_key_field_attribute(field: &Field) -> syn::Result<Option<CacheKeyFieldAttributes>> {
if let Some(attribute) = field
.attrs
.iter()
.find(|attribute| attribute.path().is_ident("cache_key"))
{
attribute.parse_args::<CacheKeyFieldAttributes>().map(Some)
} else {
Ok(None)
}
}
#[derive(Debug, Default)]
struct CacheKeyFieldAttributes {
ignore: bool,
}
impl Parse for CacheKeyFieldAttributes {
fn parse(input: ParseStream) -> syn::Result<Self> {
let mut attributes = CacheKeyFieldAttributes::default();
let args = input.parse_terminated(Ident::parse, Token![,])?;
for arg in args {
match arg.to_string().as_str() {
"ignore" => {
attributes.ignore = true;
}
name => {
return Err(Error::new(
arg.span(),
format!("Unknown `cache_field` argument {name}"),
))
}
}
}
Ok(attributes)
}
}

View file

@ -33,7 +33,11 @@ pub fn derive_combine_options(input: TokenStream) -> TokenStream {
.into()
}
#[proc_macro_derive(CacheKey)]
/// Generates a [`CacheKey`] implementation for the attributed type.
///
/// Struct fields can be attributed with the `cache_key` field-attribute that supports:
/// * `ignore`: Ignore the attributed field in the cache key
#[proc_macro_derive(CacheKey, attributes(cache_key))]
pub fn cache_key(input: TokenStream) -> TokenStream {
let item = parse_macro_input!(input as DeriveInput);