mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 05:15:00 +00:00

## Summary The bulk of the change is copied directly from Ruff: -dc8db1afb0/crates/ruff_workspace/src/options_base.rs
-dc8db1afb0/crates/ruff_macros/src/config.rs
51 lines
1.3 KiB
Rust
51 lines
1.3 KiB
Rust
mod options_metadata;
|
|
|
|
use proc_macro::TokenStream;
|
|
use quote::quote;
|
|
use syn::{parse_macro_input, DeriveInput};
|
|
|
|
#[proc_macro_derive(OptionsMetadata, attributes(option, doc, option_group))]
|
|
pub fn derive_options_metadata(input: TokenStream) -> TokenStream {
|
|
let input = parse_macro_input!(input as DeriveInput);
|
|
|
|
options_metadata::derive_impl(input)
|
|
.unwrap_or_else(syn::Error::into_compile_error)
|
|
.into()
|
|
}
|
|
|
|
#[proc_macro_derive(CombineOptions)]
|
|
pub fn derive_combine(input: TokenStream) -> TokenStream {
|
|
let input = parse_macro_input!(input as DeriveInput);
|
|
impl_combine(&input)
|
|
}
|
|
|
|
fn impl_combine(ast: &DeriveInput) -> TokenStream {
|
|
let name = &ast.ident;
|
|
let fields = if let syn::Data::Struct(syn::DataStruct {
|
|
fields: syn::Fields::Named(ref fields),
|
|
..
|
|
}) = ast.data
|
|
{
|
|
&fields.named
|
|
} else {
|
|
unimplemented!();
|
|
};
|
|
|
|
let combines = fields.iter().map(|f| {
|
|
let name = &f.ident;
|
|
quote! {
|
|
#name: self.#name.combine(other.#name)
|
|
}
|
|
});
|
|
|
|
let gen = quote! {
|
|
impl crate::Combine for #name {
|
|
fn combine(self, other: #name) -> #name {
|
|
#name {
|
|
#(#combines),*
|
|
}
|
|
}
|
|
}
|
|
};
|
|
gen.into()
|
|
}
|