diff --git a/crates/ruff/src/settings/options_base.rs b/crates/ruff/src/settings/options_base.rs index edbec37043..15e84483f2 100644 --- a/crates/ruff/src/settings/options_base.rs +++ b/crates/ruff/src/settings/options_base.rs @@ -1,24 +1,17 @@ pub trait ConfigurationOptions { - fn get_available_options() -> Vec; + fn get_available_options() -> Vec<(&'static str, OptionEntry)>; } #[derive(Debug)] pub enum OptionEntry { Field(OptionField), - Group(OptionGroup), + Group(Vec<(&'static str, OptionEntry)>), } #[derive(Debug)] pub struct OptionField { - pub name: &'static str, pub doc: &'static str, pub default: &'static str, pub value_type: &'static str, pub example: &'static str, } - -#[derive(Debug)] -pub struct OptionGroup { - pub name: &'static str, - pub fields: Vec, -} diff --git a/crates/ruff_dev/src/generate_options.rs b/crates/ruff_dev/src/generate_options.rs index 3e641ff90c..9b00476cdd 100644 --- a/crates/ruff_dev/src/generate_options.rs +++ b/crates/ruff_dev/src/generate_options.rs @@ -18,8 +18,8 @@ pub struct Args { pub(crate) dry_run: bool, } -fn emit_field(output: &mut String, field: &OptionField, group_name: Option<&str>) { - output.push_str(&format!("#### [`{0}`](#{0})\n", field.name)); +fn emit_field(output: &mut String, name: &str, field: &OptionField, group_name: Option<&str>) { + output.push_str(&format!("#### [`{0}`](#{0})\n", name)); output.push('\n'); output.push_str(field.doc); output.push_str("\n\n"); @@ -42,49 +42,24 @@ fn emit_field(output: &mut String, field: &OptionField, group_name: Option<&str> pub fn main(args: &Args) -> Result<()> { let mut output = String::new(); + let mut sorted_options = Options::get_available_options(); + sorted_options.sort_by_key(|(name, _)| *name); + // Generate all the top-level fields. - for field in Options::get_available_options() - .into_iter() - .filter_map(|entry| { - if let OptionEntry::Field(field) = entry { - Some(field) - } else { - None - } - }) - .sorted_by_key(|field| field.name) - { - emit_field(&mut output, &field, None); + for (name, entry) in &sorted_options { + let OptionEntry::Field(field) = entry else { continue; }; + emit_field(&mut output, name, field, None); output.push_str("---\n\n"); } // Generate all the sub-groups. - for group in Options::get_available_options() - .into_iter() - .filter_map(|entry| { - if let OptionEntry::Group(group) = entry { - Some(group) - } else { - None - } - }) - .sorted_by_key(|group| group.name) - { - output.push_str(&format!("### `{}`\n", group.name)); + for (group_name, entry) in &sorted_options { + let OptionEntry::Group(fields) = entry else { continue; }; + output.push_str(&format!("### `{}`\n", group_name)); output.push('\n'); - for field in group - .fields - .iter() - .filter_map(|entry| { - if let OptionEntry::Field(field) = entry { - Some(field) - } else { - None - } - }) - .sorted_by_key(|field| field.name) - { - emit_field(&mut output, field, Some(group.name)); + for (name, entry) in fields.iter().sorted_by_key(|(name, _)| name) { + let OptionEntry::Field(field) = entry else { continue; }; + emit_field(&mut output, name, field, Some(group_name)); output.push_str("---\n\n"); } } diff --git a/crates/ruff_macros/src/config.rs b/crates/ruff_macros/src/config.rs index 7f52e690e1..484724842a 100644 --- a/crates/ruff_macros/src/config.rs +++ b/crates/ruff_macros/src/config.rs @@ -45,11 +45,11 @@ pub fn derive_impl(input: DeriveInput) -> syn::Result } Ok(quote! { - use crate::settings::options_base::{OptionEntry, OptionField, OptionGroup, ConfigurationOptions}; + use crate::settings::options_base::{OptionEntry, OptionField, ConfigurationOptions}; #[automatically_derived] impl ConfigurationOptions for #ident { - fn get_available_options() -> Vec { + fn get_available_options() -> Vec<(&'static str, OptionEntry)> { vec![#(#output),*] } } @@ -86,10 +86,7 @@ fn handle_option_group(field: &Field) -> syn::Result { let kebab_name = LitStr::new(&ident.to_string().replace('_', "-"), ident.span()); Ok(quote_spanned!( - ident.span() => OptionEntry::Group(OptionGroup { - name: #kebab_name, - fields: #path::get_available_options(), - }) + ident.span() => (#kebab_name, OptionEntry::Group(#path::get_available_options())) )) } _ => Err(syn::Error::new( @@ -148,13 +145,12 @@ fn handle_option( let kebab_name = LitStr::new(&ident.to_string().replace('_', "-"), ident.span()); Ok(quote_spanned!( - ident.span() => OptionEntry::Field(OptionField { - name: #kebab_name, + ident.span() => (#kebab_name, OptionEntry::Field(OptionField { doc: &#doc, default: &#default, value_type: &#value_type, example: &#example, - }) + })) )) }