Simplify KeyGroup

The trait will only be used for documenting the key bindings in the F1
menu from now on. The InputEvent will be directly match-eable against
KeyBinding-s, which should suffice for input event handling.
This commit is contained in:
Joscha 2023-04-27 21:37:48 +02:00
parent 6ce2afbc9f
commit 64a7e7f518
2 changed files with 13 additions and 33 deletions

View file

@ -8,7 +8,5 @@ pub use keys::*;
/// A group of related key bindings. /// A group of related key bindings.
pub trait KeyGroup { pub trait KeyGroup {
type Event; fn bindings(&self) -> Vec<(&KeyBinding, &'static str)>;
fn match_input_event(&self, event: &mut InputEvent) -> Option<Self::Event>;
} }

View file

@ -1,6 +1,5 @@
use case::CaseExt;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote}; use quote::quote;
use syn::spanned::Spanned; use syn::spanned::Spanned;
use syn::{Data, DeriveInput}; use syn::{Data, DeriveInput};
@ -17,46 +16,29 @@ fn decapitalize(s: &str) -> String {
pub fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> { pub fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
let Data::Struct(data) = input.data else { let Data::Struct(data) = input.data else {
return util::bail(input.span(), "Must be a struct"); return util::bail(input.span(), "must be a struct");
}; };
let struct_ident = input.ident; let mut bindings = vec![];
let enum_ident = format_ident!("{}Event", struct_ident);
let mut enum_variants = vec![];
let mut match_cases = vec![];
for field in &data.fields { for field in &data.fields {
if let Some(field_ident) = &field.ident { if let Some(field_ident) = &field.ident {
let docstring = util::docstring(field)?; let docstring = util::docstring(field)?;
let variant_ident = format_ident!("{}", field_ident.to_string().to_camel());
enum_variants.push(quote! {
#[doc = #docstring]
#variant_ident,
});
let description = decapitalize(&docstring); let description = decapitalize(&docstring);
let description = description.strip_suffix('.').unwrap_or(&description); let description = description.strip_suffix('.').unwrap_or(&description);
match_cases.push(quote!{
() if event.matches_key_binding(&self.#field_ident, #description) => Some(Self::Event::#variant_ident), bindings.push(quote! {
(&self.#field_ident, #description)
}); });
} }
} }
let ident = input.ident;
Ok(quote! { Ok(quote! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)] impl ::cove_input::KeyGroup for #ident {
pub enum #enum_ident { fn bindings(&self) -> Vec<(&::cove_input::KeyBinding, &'static str)> {
#( #enum_variants )* vec![
} #( #bindings, )*
]
impl ::cove_input::KeyGroup for #struct_ident {
type Event = #enum_ident;
fn match_input_event(&self, event: &mut ::cove_input::InputEvent) -> Option<Self::Event> {
match () {
#( #match_cases )*
() => None,
}
} }
} }
}) })