feat(core): Add error types, config, and data model for items and events.

This commit is contained in:
2026-03-13 21:55:11 -04:00
parent de0431778f
commit 9ed8e898a5
7 changed files with 324 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
//! Types that flow between the menu engine and frontends.
//!
//! - [`Action`]: commands sent into the menu (keypresses,
//! script actions).
//! - [`MenuEvent`]: notifications sent out to subscribers
//! (state changes, terminal events).
//! - [`ViewState`]: snapshot of what the frontend should
//! render right now.
use std::sync::Arc;
use serde_json::Value;
/// A command the menu should process. Frontends and headless
/// scripts both produce these. The menu loop consumes them
/// sequentially.
#[derive(Debug, Clone, PartialEq)]
pub enum Action {
UpdateFilter(String),
MoveUp(usize),
MoveDown(usize),
MoveToTop,
MoveToBottom,
PageUp(usize),
PageDown(usize),
Confirm,
Cancel,
Resize { height: u16 },
AddItems(Vec<Value>),
}
/// Broadcast from the menu loop to all subscribers
/// (frontends, tests).
#[derive(Debug, Clone)]
pub enum MenuEvent {
StateChanged(ViewState),
Selected(Value),
Cancelled,
}
/// Snapshot of the menu's visible state. Sent on every state
/// change so frontends can render without querying back into
/// the engine.
#[must_use]
#[derive(Debug, Clone)]
pub struct ViewState {
pub visible_items: Vec<VisibleItem>,
/// Index of the cursor within `visible_items`
/// (not the full list).
pub cursor: usize,
pub filter_text: Arc<str>,
pub total_items: usize,
pub total_filtered: usize,
}
/// A single item in the current viewport window. Has the
/// display label pre-resolved and the position in the
/// filtered list.
#[must_use]
#[derive(Debug, Clone)]
pub struct VisibleItem {
pub label: String,
pub index: usize,
}
/// Final outcome of [`crate::menu::MenuRunner::run`]. The
/// user either picked something or bailed.
#[must_use]
#[derive(Debug)]
pub enum MenuResult {
Selected(Value),
Cancelled,
}