Adopt clap::ValueEnum for Group and tidy menu view

- Derive `ValueEnum` for `Group` and remove its custom `iter` method.
- Update keybindings widget to use `Group::value_variants()` and adjust
  containment and filtering logic.
- Replace view option generation with a `format_view_string` helper that
  inserts a space before the second capital letter, eliminating the
  previous filter for “MAIN MENU”.
- Adjust imports to include `clap::ValueEnum` where needed.
This commit is contained in:
2026-03-14 20:13:41 +01:00
parent 61e9dedfe8
commit 3d0aa42d7d
3 changed files with 28 additions and 33 deletions
+2 -9
View File
@@ -1,3 +1,4 @@
use clap::ValueEnum;
use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers}; use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -11,21 +12,13 @@ pub enum Action {
Esc, Esc,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)]
pub enum Group { pub enum Group {
Movement, Movement,
Select, Select,
Quit, Quit,
} }
impl Group {
pub fn iter() -> impl Iterator<Item = Group> {
[Group::Movement, Group::Select, Group::Quit]
.iter()
.copied()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct KeyBinding { pub struct KeyBinding {
pub action: Action, pub action: Action,
+22 -21
View File
@@ -12,22 +12,18 @@ use ratatui::{
widgets::{Block, Borders, Paragraph, Widget}, widgets::{Block, Borders, Paragraph, Widget},
}; };
fn view_options() -> Vec<(usize, String)> { fn format_view_string(s: String) -> String {
View::value_variants() if let Some(pos) = s
.iter() .char_indices()
.enumerate() .filter(|(_, c)| c.is_ascii_uppercase())
.filter_map(|(i, v)| { .nth(1)
v.to_possible_value().map(|possible_value| { .map(|(i, _)| i)
let name = possible_value {
.get_name() let (first, second) = s.split_at(pos);
.replace('-', " ") format!("{first} {second}")
.to_uppercase() } else {
.to_string(); s
(i, name) }
})
})
.filter(|(_, v)| v != "MAIN MENU")
.collect()
} }
pub fn main_menu_view(app: &App, area: Rect, buf: &mut Buffer) { pub fn main_menu_view(app: &App, area: Rect, buf: &mut Buffer) {
@@ -66,14 +62,19 @@ pub fn main_menu_view(app: &App, area: Rect, buf: &mut Buffer) {
{ {
let options_area: Rect = main_menu_areas[1]; let options_area: Rect = main_menu_areas[1];
let lines: Vec<Line<'_>> = view_options() let lines: Vec<Line<'_>> = View::value_variants()
.into_iter() .iter()
.enumerate()
.filter(|(_, v)| v != &&View::MainMenu)
.map(|(i, view)| { .map(|(i, view)| {
let styled = if app.game_states.main_menu_state.selected_view == i { let view_string: String = format_view_string(format!("{:?}", view));
Line::from(format!("> {}", view)).yellow()
let styled: Line<'_> = if app.game_states.main_menu_state.selected_view == i {
Line::from(format!("> {view_string}")).yellow()
} else { } else {
Line::from(view).white() Line::from(view_string).white()
}; };
styled styled
}) })
.collect(); .collect();
+4 -3
View File
@@ -1,6 +1,7 @@
use std::collections::HashSet; use std::collections::HashSet;
use crate::app::keybindings::{Group, KeyBinding}; use crate::app::keybindings::{Group, KeyBinding};
use clap::ValueEnum;
use ratatui::{ use ratatui::{
buffer::Buffer, buffer::Buffer,
layout::{Alignment, Constraint, Layout, Rect}, layout::{Alignment, Constraint, Layout, Rect},
@@ -21,14 +22,14 @@ impl KeybindingsWidget {
.collect(); .collect();
let mut grouped_keybindings: Vec<Paragraph<'static>> = Vec::new(); let mut grouped_keybindings: Vec<Paragraph<'static>> = Vec::new();
for (i, group) in Group::iter().enumerate() { for (i, group) in Group::value_variants().iter().enumerate() {
if !used_groups.contains(&group) { if !used_groups.contains(group) {
continue; continue;
} }
let grouped_lines: Vec<Line<'_>> = keybindings let grouped_lines: Vec<Line<'_>> = keybindings
.iter() .iter()
.filter(|b| b.as_ref().map_or(false, |kb| kb.group == group)) .filter(|b| b.as_ref().map_or(false, |kb| kb.group == *group))
.filter_map(|b| { .filter_map(|b| {
b.as_ref().map(|kb| { b.as_ref().map(|kb| {
Line::from_iter([ Line::from_iter([