refactor: Move name out of OptionField & OptionGroup

This commit is contained in:
Martin Fischer 2023-02-11 18:07:16 +01:00 committed by Charlie Marsh
parent 37e80d98ab
commit bbe44360e8
3 changed files with 21 additions and 57 deletions

View file

@ -1,24 +1,17 @@
pub trait ConfigurationOptions { pub trait ConfigurationOptions {
fn get_available_options() -> Vec<OptionEntry>; fn get_available_options() -> Vec<(&'static str, OptionEntry)>;
} }
#[derive(Debug)] #[derive(Debug)]
pub enum OptionEntry { pub enum OptionEntry {
Field(OptionField), Field(OptionField),
Group(OptionGroup), Group(Vec<(&'static str, OptionEntry)>),
} }
#[derive(Debug)] #[derive(Debug)]
pub struct OptionField { pub struct OptionField {
pub name: &'static str,
pub doc: &'static str, pub doc: &'static str,
pub default: &'static str, pub default: &'static str,
pub value_type: &'static str, pub value_type: &'static str,
pub example: &'static str, pub example: &'static str,
} }
#[derive(Debug)]
pub struct OptionGroup {
pub name: &'static str,
pub fields: Vec<OptionEntry>,
}

View file

@ -18,8 +18,8 @@ pub struct Args {
pub(crate) dry_run: bool, pub(crate) dry_run: bool,
} }
fn emit_field(output: &mut String, field: &OptionField, group_name: Option<&str>) { fn emit_field(output: &mut String, name: &str, field: &OptionField, group_name: Option<&str>) {
output.push_str(&format!("#### [`{0}`](#{0})\n", field.name)); output.push_str(&format!("#### [`{0}`](#{0})\n", name));
output.push('\n'); output.push('\n');
output.push_str(field.doc); output.push_str(field.doc);
output.push_str("\n\n"); 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<()> { pub fn main(args: &Args) -> Result<()> {
let mut output = String::new(); 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. // Generate all the top-level fields.
for field in Options::get_available_options() for (name, entry) in &sorted_options {
.into_iter() let OptionEntry::Field(field) = entry else { continue; };
.filter_map(|entry| { emit_field(&mut output, name, field, None);
if let OptionEntry::Field(field) = entry {
Some(field)
} else {
None
}
})
.sorted_by_key(|field| field.name)
{
emit_field(&mut output, &field, None);
output.push_str("---\n\n"); output.push_str("---\n\n");
} }
// Generate all the sub-groups. // Generate all the sub-groups.
for group in Options::get_available_options() for (group_name, entry) in &sorted_options {
.into_iter() let OptionEntry::Group(fields) = entry else { continue; };
.filter_map(|entry| { output.push_str(&format!("### `{}`\n", group_name));
if let OptionEntry::Group(group) = entry {
Some(group)
} else {
None
}
})
.sorted_by_key(|group| group.name)
{
output.push_str(&format!("### `{}`\n", group.name));
output.push('\n'); output.push('\n');
for field in group for (name, entry) in fields.iter().sorted_by_key(|(name, _)| name) {
.fields let OptionEntry::Field(field) = entry else { continue; };
.iter() emit_field(&mut output, name, field, Some(group_name));
.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));
output.push_str("---\n\n"); output.push_str("---\n\n");
} }
} }

View file

@ -45,11 +45,11 @@ pub fn derive_impl(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream>
} }
Ok(quote! { Ok(quote! {
use crate::settings::options_base::{OptionEntry, OptionField, OptionGroup, ConfigurationOptions}; use crate::settings::options_base::{OptionEntry, OptionField, ConfigurationOptions};
#[automatically_derived] #[automatically_derived]
impl ConfigurationOptions for #ident { impl ConfigurationOptions for #ident {
fn get_available_options() -> Vec<OptionEntry> { fn get_available_options() -> Vec<(&'static str, OptionEntry)> {
vec![#(#output),*] vec![#(#output),*]
} }
} }
@ -86,10 +86,7 @@ fn handle_option_group(field: &Field) -> syn::Result<proc_macro2::TokenStream> {
let kebab_name = LitStr::new(&ident.to_string().replace('_', "-"), ident.span()); let kebab_name = LitStr::new(&ident.to_string().replace('_', "-"), ident.span());
Ok(quote_spanned!( Ok(quote_spanned!(
ident.span() => OptionEntry::Group(OptionGroup { ident.span() => (#kebab_name, OptionEntry::Group(#path::get_available_options()))
name: #kebab_name,
fields: #path::get_available_options(),
})
)) ))
} }
_ => Err(syn::Error::new( _ => Err(syn::Error::new(
@ -148,13 +145,12 @@ fn handle_option(
let kebab_name = LitStr::new(&ident.to_string().replace('_', "-"), ident.span()); let kebab_name = LitStr::new(&ident.to_string().replace('_', "-"), ident.span());
Ok(quote_spanned!( Ok(quote_spanned!(
ident.span() => OptionEntry::Field(OptionField { ident.span() => (#kebab_name, OptionEntry::Field(OptionField {
name: #kebab_name,
doc: &#doc, doc: &#doc,
default: &#default, default: &#default,
value_type: &#value_type, value_type: &#value_type,
example: &#example, example: &#example,
}) }))
)) ))
} }