mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 21:05:08 +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.")),
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue