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,41 @@
//! Trait abstractions for the menu data layer. [`Menu`]
//! is what the event loop drives. [`MenuItem`] is the display
//! contract for a single entry. Different backends (JSON,
//! CSV, Postgres, etc.) implement these.
/// Display contract for a single entry in a menu.
/// Provides a label for display and serialization for output.
pub trait MenuItem: Send + Sync + 'static {
/// Human-readable display text for this entry.
fn label(&self) -> &str;
/// Serialize this entry for structured output (stdout, hooks).
fn serialize(&self) -> serde_json::Value;
}
/// A filterable collection that the menu event loop drives.
/// Each implementation owns its data and handles filtering
/// internally. The event loop only needs labels (strings)
/// and serialized output (JSON values).
pub trait Menu: Send + 'static {
/// Total number of items before filtering.
fn total(&self) -> usize;
/// Apply a filter query. Implementations decide how to
/// match (fuzzy, regex, exact, SQL WHERE, etc.).
fn apply_filter(&mut self, query: &str);
/// Number of items that passed the current filter.
fn filtered_count(&self) -> usize;
/// Get the display label for a filtered item by its
/// position in the filtered results.
fn filtered_label(&self, filtered_index: usize) -> Option<&str>;
/// Add raw values from streaming input or AddItems actions.
fn add_raw(&mut self, values: Vec<serde_json::Value>);
/// Get the JSON value of a filtered item for output.
/// Returns a reference to the stored value.
fn serialize_filtered(&self, filtered_index: usize) -> Option<&serde_json::Value>;
}