mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-24 13:33:50 +00:00
Merge subsettings when extending configurations (#4431)
This commit is contained in:
parent
f70c286e6a
commit
d6930ca991
24 changed files with 197 additions and 64 deletions
62
crates/ruff_macros/src/combine_options.rs
Normal file
62
crates/ruff_macros/src/combine_options.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
use quote::{quote, quote_spanned};
|
||||
use syn::{Data, DataStruct, DeriveInput, Field, Fields, Path, PathSegment, Type, TypePath};
|
||||
|
||||
pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
|
||||
let DeriveInput { ident, data, .. } = input;
|
||||
|
||||
match data {
|
||||
Data::Struct(DataStruct {
|
||||
fields: Fields::Named(fields),
|
||||
..
|
||||
}) => {
|
||||
let output = fields
|
||||
.named
|
||||
.iter()
|
||||
.map(handle_field)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(quote! {
|
||||
use crate::settings::configuration::CombinePluginOptions;
|
||||
|
||||
impl CombinePluginOptions for #ident {
|
||||
fn combine(self, other: Self) -> Self {
|
||||
Self {
|
||||
#(
|
||||
#output
|
||||
),*
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => Err(syn::Error::new(
|
||||
ident.span(),
|
||||
"Can only derive CombineOptions from structs with named fields.",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_field(field: &Field) -> syn::Result<proc_macro2::TokenStream> {
|
||||
let ident = field
|
||||
.ident
|
||||
.as_ref()
|
||||
.expect("Expected to handle named fields");
|
||||
|
||||
match &field.ty {
|
||||
Type::Path(TypePath {
|
||||
path: Path { segments, .. },
|
||||
..
|
||||
}) => match segments.first() {
|
||||
Some(PathSegment {
|
||||
ident: type_ident, ..
|
||||
}) if type_ident == "Option" => Ok(quote_spanned!(
|
||||
ident.span() => #ident: self.#ident.or(other.#ident)
|
||||
)),
|
||||
_ => Err(syn::Error::new(
|
||||
ident.span(),
|
||||
"Expected `Option<_>` or `Vec<_>` as type.",
|
||||
)),
|
||||
},
|
||||
_ => Err(syn::Error::new(ident.span(), "Expected type.")),
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ use proc_macro::TokenStream;
|
|||
use syn::{parse_macro_input, DeriveInput, ItemFn, ItemStruct};
|
||||
|
||||
mod cache_key;
|
||||
mod combine_options;
|
||||
mod config;
|
||||
mod derive_message_formats;
|
||||
mod map_codes;
|
||||
|
@ -22,6 +23,15 @@ pub fn derive_config(input: proc_macro::TokenStream) -> proc_macro::TokenStream
|
|||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(CombineOptions)]
|
||||
pub fn derive_combine_options(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
|
||||
combine_options::derive_impl(input)
|
||||
.unwrap_or_else(syn::Error::into_compile_error)
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(CacheKey)]
|
||||
pub fn cache_key(input: TokenStream) -> TokenStream {
|
||||
let item = parse_macro_input!(input as DeriveInput);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue