Provide list of key groups in config crate
This also fixes the f1 menu not displaying the room group.
This commit is contained in:
parent
48279e879a
commit
101d36cd45
6 changed files with 93 additions and 50 deletions
|
|
@ -16,12 +16,12 @@ struct FieldInfo {
|
|||
|
||||
impl FieldInfo {
|
||||
fn initialize_from_field(&mut self, field: &Field) -> syn::Result<()> {
|
||||
let docstring = util::docstring(field)?;
|
||||
let docstring = util::docstring(&field.attrs)?;
|
||||
if !docstring.is_empty() {
|
||||
self.description = Some(docstring);
|
||||
}
|
||||
|
||||
for arg in util::attribute_arguments(field, "document")? {
|
||||
for arg in util::attribute_arguments(&field.attrs, "document")? {
|
||||
if arg.path.is_ident("metavar") {
|
||||
// Parse `#[document(metavar = "bla")]`
|
||||
if let Some(metavar) = arg.value.and_then(util::into_litstr) {
|
||||
|
|
|
|||
|
|
@ -19,11 +19,16 @@ pub fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||
return util::bail(input.span(), "must be a struct");
|
||||
};
|
||||
|
||||
let docstring = util::docstring(&input.attrs)?;
|
||||
let description = docstring.strip_suffix('.').unwrap_or(&docstring);
|
||||
|
||||
let mut bindings = vec![];
|
||||
let mut defaults = vec![];
|
||||
for field in &data.fields {
|
||||
if let Some(field_ident) = &field.ident {
|
||||
let docstring = util::docstring(field)?;
|
||||
let field_name = field_ident.to_string();
|
||||
|
||||
let docstring = util::docstring(&field.attrs)?;
|
||||
let description = decapitalize(&docstring);
|
||||
let description = description.strip_suffix('.').unwrap_or(&description);
|
||||
|
||||
|
|
@ -34,7 +39,11 @@ pub fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||
let default_value = default.value();
|
||||
|
||||
bindings.push(quote! {
|
||||
(&self.#field_ident, #description)
|
||||
::cove_input::KeyBindingInfo {
|
||||
name: #field_name,
|
||||
binding: &self.#field_ident,
|
||||
description: #description
|
||||
}
|
||||
});
|
||||
|
||||
defaults.push(quote! {
|
||||
|
|
@ -46,7 +55,9 @@ pub fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
|
|||
let ident = input.ident;
|
||||
Ok(quote! {
|
||||
impl ::cove_input::KeyGroup for #ident {
|
||||
fn bindings(&self) -> Vec<(&::cove_input::KeyBinding, &'static str)> {
|
||||
const DESCRIPTION: &'static str = #description;
|
||||
|
||||
fn bindings(&self) -> Vec<::cove_input::KeyBindingInfo<'_>> {
|
||||
vec![
|
||||
#( #bindings, )*
|
||||
]
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use proc_macro2::{Span, TokenStream};
|
|||
use quote::quote;
|
||||
use syn::parse::Parse;
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::{Expr, ExprLit, ExprPath, Field, Lit, LitStr, Path, Token, Type};
|
||||
use syn::{Attribute, Expr, ExprLit, ExprPath, Field, Lit, LitStr, Path, Token, Type};
|
||||
|
||||
pub fn bail<T>(span: Span, message: &str) -> syn::Result<T> {
|
||||
Err(syn::Error::new(span, message))
|
||||
|
|
@ -28,14 +28,10 @@ pub fn into_litstr(expr: Expr) -> Option<LitStr> {
|
|||
|
||||
/// Given a struct field, this finds all attributes like `#[doc = "bla"]`,
|
||||
/// unindents, concatenates and returns them.
|
||||
pub fn docstring(field: &Field) -> syn::Result<String> {
|
||||
pub fn docstring(attributes: &[Attribute]) -> syn::Result<String> {
|
||||
let mut lines = vec![];
|
||||
|
||||
for attr in field
|
||||
.attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path().is_ident("doc"))
|
||||
{
|
||||
for attr in attributes.iter().filter(|attr| attr.path().is_ident("doc")) {
|
||||
if let Some(lit) = litstr(&attr.meta.require_name_value()?.value) {
|
||||
let value = lit.value();
|
||||
let value = value
|
||||
|
|
@ -70,16 +66,19 @@ impl Parse for AttributeArgument {
|
|||
/// Given a struct field, this finds all arguments of the form `#[path(key)]`
|
||||
/// and `#[path(key = value)]`. Multiple arguments may be specified in a single
|
||||
/// annotation, e.g. `#[foo(bar, baz = true)]`.
|
||||
pub fn attribute_arguments(field: &Field, path: &str) -> syn::Result<Vec<AttributeArgument>> {
|
||||
let mut attrs = vec![];
|
||||
pub fn attribute_arguments(
|
||||
attributes: &[Attribute],
|
||||
path: &str,
|
||||
) -> syn::Result<Vec<AttributeArgument>> {
|
||||
let mut attr_args = vec![];
|
||||
|
||||
for attr in field.attrs.iter().filter(|attr| attr.path().is_ident(path)) {
|
||||
for attr in attributes.iter().filter(|attr| attr.path().is_ident(path)) {
|
||||
let args =
|
||||
attr.parse_args_with(Punctuated::<AttributeArgument, Token![,]>::parse_terminated)?;
|
||||
attrs.extend(args);
|
||||
attr_args.extend(args);
|
||||
}
|
||||
|
||||
Ok(attrs)
|
||||
Ok(attr_args)
|
||||
}
|
||||
|
||||
pub enum SerdeDefault {
|
||||
|
|
@ -102,7 +101,7 @@ impl SerdeDefault {
|
|||
|
||||
/// Find `#[serde(default)]` or `#[serde(default = "bla")]`.
|
||||
pub fn serde_default(field: &Field) -> syn::Result<Option<SerdeDefault>> {
|
||||
for arg in attribute_arguments(field, "serde")? {
|
||||
for arg in attribute_arguments(&field.attrs, "serde")? {
|
||||
if arg.path.is_ident("default") {
|
||||
if let Some(value) = arg.value {
|
||||
if let Some(path) = into_litstr(value) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue