Expand description
Core traits and types for tui-dispatch
This crate provides the foundational abstractions for building TUI applications with centralized state management, following a Redux/Elm-inspired architecture.
§Core Concepts
- Action: Events that describe state changes
- Store: Centralized state container with reducer pattern
- Component: Pure UI elements that render based on props
- EventBus: Pub/sub system for event routing
- Keybindings: Context-aware key mapping
§Basic Example
ⓘ
use tui_dispatch_core::prelude::*;
#[derive(Action, Clone, Debug)]
enum MyAction {
Increment,
Decrement,
}
#[derive(Default)]
struct AppState {
counter: i32,
}
fn reducer(state: &mut AppState, action: MyAction) -> bool {
match action {
MyAction::Increment => { state.counter += 1; true }
MyAction::Decrement => { state.counter -= 1; true }
}
}
let mut store = Store::new(AppState::default(), reducer);
store.dispatch(MyAction::Increment);§Async Handler Pattern
For applications with async operations (API calls, file I/O, etc.), use a two-phase action pattern:
- Intent actions trigger async work (e.g.,
FetchData) - Result actions carry the outcome back (e.g.,
DidFetchData,DidFetchError)
ⓘ
use tokio::sync::mpsc;
#[derive(Action, Clone, Debug)]
#[action(infer_categories)]
enum Action {
// Intent: triggers async fetch
DataFetch { id: String },
// Result: async operation completed
DataDidLoad { id: String, payload: Vec<u8> },
DataDidError { id: String, error: String },
}
// Async handler spawns a task and sends result back via channel
fn handle_async(action: &Action, tx: mpsc::UnboundedSender<Action>) {
match action {
Action::DataFetch { id } => {
let id = id.clone();
let tx = tx.clone();
tokio::spawn(async move {
match fetch_from_api(&id).await {
Ok(payload) => tx.send(Action::DataDidLoad { id, payload }),
Err(e) => tx.send(Action::DataDidError { id, error: e.to_string() }),
}
});
}
_ => {}
}
}
// Main loop receives actions from both events and async completions
loop {
tokio::select! {
Some(action) = action_rx.recv() => {
handle_async(&action, action_tx.clone());
store.dispatch(action);
}
// ... event handling
}
}The Did* naming convention clearly identifies result actions. With #[action(infer_categories)],
these are automatically grouped (e.g., DataFetch and DataDidLoad both get category "data").
Re-exports§
pub use action::Action;pub use action::ActionCategory;pub use component::Component;pub use bus::process_raw_event;pub use bus::spawn_event_poller;pub use bus::EventBus;pub use bus::RawEvent;pub use event::ComponentId;pub use event::Event;pub use event::EventContext;pub use event::EventKind;pub use event::EventType;pub use event::NumericComponentId;pub use keybindings::format_key_for_display;pub use keybindings::parse_key_string;pub use keybindings::BindingContext;pub use keybindings::Keybindings;pub use store::ComposedMiddleware;pub use store::LoggingMiddleware;pub use store::Middleware;pub use store::NoopMiddleware;pub use store::Reducer;pub use store::Store;pub use store::StoreWithMiddleware;pub use testing::alt_key;pub use testing::buffer_rect_to_string_plain;pub use testing::buffer_to_string;pub use testing::buffer_to_string_plain;pub use testing::char_key;pub use testing::ctrl_key;pub use testing::into_event;pub use testing::key;pub use testing::key_event;pub use testing::key_events;pub use testing::keys;pub use testing::ActionAssertions;pub use testing::ActionAssertionsEq;pub use testing::RenderHarness;pub use testing::TestHarness;
Modules§
- action
- Action trait for type-safe state mutations
- bus
- Event bus for dispatching events to subscribed components
- component
- Component trait for pure UI elements
- debug
- Debug and inspection utilities for TUI applications
- event
- Event types for the pub/sub system
- keybindings
- Keybindings system with context-aware key parsing and lookup
- prelude
- Prelude module for convenient imports
- store
- Centralized state store with reducer pattern
- testing
- Test utilities for tui-dispatch applications
Macros§
- assert_
category_ emitted - Assert that an action of a specific category was emitted.
- assert_
category_ not_ emitted - Assert that NO action of a specific category was emitted.
- assert_
emitted - Assert that a specific action was emitted.
- assert_
not_ emitted - Assert that a specific action was NOT emitted.
- assert_
state - Assert that a field of the harness state has an expected value.
- assert_
state_ matches - Assert that a field of the harness state matches a pattern.
- count_
category - Count how many actions belong to a specific category.
- count_
emitted - Count how many actions match a pattern.
- find_
emitted - Find and return the first action matching a pattern.
Structs§
- Frame
- A consistent view into the terminal state for rendering a single frame.
- Line
- A line of text, consisting of one or more
Spans. - Modifier
- Modifier changes the way a piece of text is displayed.
- Rect
- A Rectangular area.
- Span
- Represents a part of a line that is contiguous and where all characters share the same style.
- Style
- Style lets you control the main characteristics of the displayed elements.
- Text
- A string split over one or more lines.
Enums§
- Color
- ANSI Color