generated from GarandPLG/rust-flake-template
Add documentation
Extensive doc comments were added to keybindings, CLI options, logging, and widget modules. The `count_largest_group` function was introduced to compute the largest group size among actions. CLI validation for `skill_points_limit` was broadened to a 90‑690 range. Imports and signatures for `Display` were adjusted accordingly.
This commit is contained in:
@@ -2,49 +2,95 @@ use clap::ValueEnum;
|
||||
use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Represents the set of actions that the UI can perform.
|
||||
///
|
||||
/// Each variant corresponds to a concrete operation that can be triggered by a
|
||||
/// key binding. The `WildCard` variant is a special case that matches any
|
||||
/// character key and carries the actual character pressed.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum Action {
|
||||
/// Request the application to quit.
|
||||
Quit,
|
||||
/// Alternate quit action.
|
||||
Quit2,
|
||||
/// Move the selection cursor up.
|
||||
Up,
|
||||
/// Move the selection cursor down.
|
||||
Down,
|
||||
/// Move the selection cursor left.
|
||||
Left,
|
||||
/// Move the selection cursor right.
|
||||
Right,
|
||||
/// Scroll up without moving the cursor.
|
||||
ScrollUp,
|
||||
/// Scroll down without moving the cursor.
|
||||
ScrollDown,
|
||||
/// Scroll left without moving the cursor.
|
||||
ScrollLeft,
|
||||
/// Scroll right without moving the cursor.
|
||||
ScrollRight,
|
||||
/// Select the current item.
|
||||
Space,
|
||||
/// Submit or confirm the current choice.
|
||||
Enter,
|
||||
/// Return to the main menu or previous screen.
|
||||
Esc,
|
||||
/// Delete the character before the cursor.
|
||||
Backspace,
|
||||
/// Zoom the view in.
|
||||
ZoomIn,
|
||||
/// Zoom the view out.
|
||||
ZoomOut,
|
||||
/// Matches any character key; the inner `char` is the actual key pressed.
|
||||
WildCard(char),
|
||||
}
|
||||
|
||||
/// Logical groups of key bindings used for organising help screens or
|
||||
/// configuration sections.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)]
|
||||
pub enum Group {
|
||||
/// Bindings that combine `Ctrl` with movement keys.
|
||||
CtrlMovement,
|
||||
/// Plain movement bindings.
|
||||
Movement,
|
||||
/// Scroll bindings.
|
||||
Scroll,
|
||||
/// Selection bindings.
|
||||
Select,
|
||||
/// Text input related bindings.
|
||||
Input,
|
||||
/// Zoom related bindings.
|
||||
Zoom,
|
||||
/// Quit related bindings.
|
||||
Quit,
|
||||
}
|
||||
|
||||
/// Description of a single key binding.
|
||||
///
|
||||
/// This struct stores the mapping from a physical key event to an `Action`,
|
||||
/// together with metadata used for displaying help information.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct KeyBinding {
|
||||
/// The logical action performed when this binding is triggered.
|
||||
pub action: Action,
|
||||
/// The raw `crossterm::event::KeyCode` that identifies the key.
|
||||
pub code: KeyCode,
|
||||
/// The kind of key event (crossterm::event::KeyEventKind).
|
||||
pub kind: KeyEventKind,
|
||||
/// Any modifier keys that must be held (crossterm::event::KeyModifiers).
|
||||
pub modifiers: KeyModifiers,
|
||||
/// The group this binding belongs to, useful for categorising help.
|
||||
pub group: Group,
|
||||
/// Human‑readable symbol shown in UI/help screens.
|
||||
pub symbol: &'static str,
|
||||
/// Short description of what the binding does.
|
||||
pub description: &'static str,
|
||||
}
|
||||
|
||||
/// Complete list of all key bindings used by the application.
|
||||
///
|
||||
/// The slice is ordered primarily for readability; the runtime lookup scans
|
||||
/// this slice linearly, which is acceptable given the modest size of the list.
|
||||
pub static KEYBINDINGS: &[KeyBinding] = &[
|
||||
KeyBinding {
|
||||
action: Action::Quit,
|
||||
@@ -201,10 +247,18 @@ pub static KEYBINDINGS: &[KeyBinding] = &[
|
||||
},
|
||||
];
|
||||
|
||||
/// Returns the `KeyBinding` associated with the given `Action`, if one exists.
|
||||
pub fn binding_for(action: Action) -> Option<&'static KeyBinding> {
|
||||
KEYBINDINGS.iter().find(|b| b.action == action)
|
||||
}
|
||||
|
||||
/// Converts a raw `KeyEvent` into an `Action` if a matching binding is found.
|
||||
///
|
||||
/// The function first looks for an exact match on code, kind, and modifiers.
|
||||
/// If no exact match exists but a wildcard binding is present for the same
|
||||
/// event kind, the function returns `Action::WildCard` with the character that
|
||||
/// was pressed. Returns `None` when the event does not correspond to any known
|
||||
/// action.
|
||||
pub fn event_to_action(event: &KeyEvent) -> Option<Action> {
|
||||
if let Some(b) = KEYBINDINGS
|
||||
.iter()
|
||||
@@ -225,6 +279,11 @@ pub fn event_to_action(event: &KeyEvent) -> Option<Action> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Determines the size of the largest group among a slice of actions.
|
||||
///
|
||||
/// It counts how many times each group appears in the supplied actions and
|
||||
/// returns the highest count. This can be used, for example, to size UI
|
||||
/// elements that display groups of bindings.
|
||||
pub fn count_largest_group(actions: &Vec<Action>) -> u16 {
|
||||
let mut group_counts: HashMap<Group, u16> = HashMap::new();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use clap::ValueEnum;
|
||||
use std::fmt::Display;
|
||||
use std::fmt::{Display, Formatter, Result};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct PerkDecksState {
|
||||
@@ -16,7 +16,7 @@ pub enum PerkDecks {
|
||||
}
|
||||
|
||||
impl Display for PerkDecks {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
match self {
|
||||
PerkDecks::Silesian => write!(f, "Silesian"),
|
||||
PerkDecks::BogeyMan => write!(f, "Bogey Man"),
|
||||
|
||||
@@ -12,11 +12,31 @@ use ratatui::{
|
||||
};
|
||||
use std::collections::HashSet;
|
||||
|
||||
/// A widget that visualises the keybindings for a set of actions.
|
||||
///
|
||||
/// The widget stores a vector of [`Paragraph`] objects, each representing one
|
||||
/// logical group of keybindings (e.g. navigation, editing, etc.). The paragraphs
|
||||
/// are rendered side‑by‑side inside a bordered container.
|
||||
pub struct KeybindingsWidget {
|
||||
/// Paragraphs, one per used `Group`, containing the formatted keybinding lines.
|
||||
grouped: Vec<Paragraph<'static>>,
|
||||
}
|
||||
|
||||
impl KeybindingsWidget {
|
||||
/// Create a new widget from a list of actions.
|
||||
///
|
||||
/// For each action, the corresponding static [`KeyBinding`] is looked up
|
||||
/// using [`binding_for`]. Only groups that have at least one binding are
|
||||
/// displayed. The resulting widget contains a paragraph for each group,
|
||||
/// formatted with the key symbol (red & bold) followed by its description.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `actions` – A vector of actions for which keybindings should be shown.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A fully‑initialised `KeybindingsWidget` ready for rendering.
|
||||
pub fn new(actions: Vec<Action>) -> Self {
|
||||
let keybindings: Vec<Option<&'static KeyBinding>> =
|
||||
actions.iter().map(|a| binding_for(*a)).collect();
|
||||
@@ -66,6 +86,14 @@ impl KeybindingsWidget {
|
||||
}
|
||||
|
||||
impl Widget for KeybindingsWidget {
|
||||
/// Render the widget inside the given rectangular area.
|
||||
///
|
||||
/// The widget first draws a surrounding border with the title *Keybindings*.
|
||||
/// It then divides the inner area into equal horizontal slices—one per
|
||||
/// used group—and renders each group's paragraph into its slice.
|
||||
///
|
||||
/// If no groups are present, the function returns early without drawing
|
||||
/// anything.
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
let count: u16 = self.grouped.len() as u16;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user