Add settings_ui(group) attribute to macro
Co-authored-by: Ben Kunkle <ben@zed.dev>
This commit is contained in:
parent
15f634f8cc
commit
ba9d109289
4 changed files with 55 additions and 8 deletions
|
@ -5,7 +5,7 @@ use git::GitHostingProviderRegistry;
|
|||
use gpui::App;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::{SettingsUI, Settings, SettingsStore};
|
||||
use settings::{Settings, SettingsStore, SettingsUI};
|
||||
use url::Url;
|
||||
use util::ResultExt as _;
|
||||
|
||||
|
|
|
@ -16,6 +16,13 @@ pub(crate) fn derive_action(input: TokenStream) -> TokenStream {
|
|||
let mut deprecated = None;
|
||||
let mut doc_str: Option<String> = None;
|
||||
|
||||
/*
|
||||
*
|
||||
* #[action()]
|
||||
* Struct Foo {
|
||||
* bar: bool // is bar considered an attribute
|
||||
}
|
||||
*/
|
||||
for attr in &input.attrs {
|
||||
if attr.path().is_ident("action") {
|
||||
attr.parse_nested_meta(|meta| {
|
||||
|
|
|
@ -11,14 +11,20 @@ pub trait SettingsUI {
|
|||
}
|
||||
|
||||
pub struct SettingsUIItem {
|
||||
// TODO:
|
||||
// path: SmallVec<[&'static str; 8]>,
|
||||
// TODO: move this back here once there isn't a None variant
|
||||
// pub path: &'static str,
|
||||
pub item: SettingsUIItemVariant,
|
||||
}
|
||||
|
||||
pub enum SettingsUIItemVariant {
|
||||
Group(SettingsUIItemGroup),
|
||||
Item(SettingsUIItemSingle),
|
||||
Group {
|
||||
path: &'static str,
|
||||
group: SettingsUIItemGroup,
|
||||
},
|
||||
Item {
|
||||
path: &'static str,
|
||||
item: SettingsUIItemSingle,
|
||||
},
|
||||
// TODO: remove
|
||||
None,
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{DeriveInput, parse_macro_input};
|
||||
use syn::{DeriveInput, LitStr, Token, parse_macro_input};
|
||||
|
||||
/// Derive macro for the `SettingsUI` marker trait.
|
||||
///
|
||||
|
@ -15,12 +15,13 @@ use syn::{DeriveInput, parse_macro_input};
|
|||
/// use settings_ui_macros::SettingsUI;
|
||||
///
|
||||
/// #[derive(SettingsUI)]
|
||||
/// #[settings_ui(group = "Standard")]
|
||||
/// struct MySettings {
|
||||
/// enabled: bool,
|
||||
/// count: usize,
|
||||
/// }
|
||||
/// ```
|
||||
#[proc_macro_derive(SettingsUI)]
|
||||
#[proc_macro_derive(SettingsUI, attributes(settings_ui))]
|
||||
pub fn derive_settings_ui(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let name = &input.ident;
|
||||
|
@ -28,8 +29,41 @@ pub fn derive_settings_ui(input: TokenStream) -> TokenStream {
|
|||
// Handle generic parameters if present
|
||||
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
||||
|
||||
let mut group_name = Option::<String>::None;
|
||||
|
||||
for attr in &input.attrs {
|
||||
if attr.path().is_ident("settings_ui") {
|
||||
attr.parse_nested_meta(|meta| {
|
||||
if meta.path.is_ident("group") {
|
||||
if group_name.is_some() {
|
||||
return Err(meta.error("Only one 'group' path can be specified"));
|
||||
}
|
||||
meta.input.parse::<Token![=]>()?;
|
||||
let lit: LitStr = meta.input.parse()?;
|
||||
group_name = Some(lit.value());
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.unwrap_or_else(|e| panic!("in #[settings_ui] attribute: {}", e));
|
||||
}
|
||||
}
|
||||
|
||||
let ui_item_fn_body = if let Some(group_name) = group_name {
|
||||
quote! {
|
||||
settings::SettingsUIItem { item: settings::SettingsUIItemVariant::Group{ path: #group_name, group: settings::SettingsUIItemGroup{ items: Default::default() } } }
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
settings::SettingsUIItem { item: settings::SettingsUIItemVariant::None }
|
||||
}
|
||||
};
|
||||
|
||||
let expanded = quote! {
|
||||
impl #impl_generics settings::SettingsUI for #name #ty_generics #where_clause {}
|
||||
impl #impl_generics settings::SettingsUI for #name #ty_generics #where_clause {
|
||||
fn ui_item() -> settings::SettingsUIItem {
|
||||
#ui_item_fn_body
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(expanded)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue