f30a2a27584ad23857f3cd5ac5fdf4ac26427638
WARNING this library is purely GLM4.7/Opus4.5 generated. Its based on a real production code that was not yet decoupled into a library. This library is core concept extracted for no_std usage. For more info visit: https://gitlab.com/filipriec/komp_ac_client
pages-tui
Type-safe TUI page routing with single-generic orchestration.
Features
| Feature | Description |
|---|---|
| (none) | Pure no_std + heapless. No allocator required. |
alloc |
Enables dynamic allocation (Vec, Box, HashMap). |
std |
Full std support (implies alloc). |
Default: Pure no_std Heapless
[dependencies]
pages-tui = "0.2"
No allocator needed! Uses heapless collections with const generic capacities.
With Allocation
[dependencies]
pages-tui = { version = "0.2", features = ["alloc"] }
Uses Vec, Box, HashMap for dynamic sizing and trait objects.
With Full Std
[dependencies]
pages-tui = { version = "0.2", features = ["std"] }
Usage
Define your page as an enum that implements the Page trait:
use pages_tui::prelude::*;
#[derive(Debug, Clone)]
enum MyPage {
Home { counter: i32 },
Settings { dark_mode: bool },
}
impl Page for MyPage {
type Focus = MyFocus;
type Action = MyAction;
type Event = MyEvent;
fn targets(&self) -> &[Self::Focus] {
match self {
MyPage::Home { .. } => &[MyFocus::Button(0)],
MyPage::Settings { .. } => &[MyFocus::Toggle],
}
}
fn handle(&mut self, focus: &Self::Focus, action: Self::Action)
-> Result<Option<Self::Event>, ComponentError>
{
// Handle actions...
Ok(None)
}
}
// Create orchestrator with single generic
let mut app: Orchestrator<MyPage> = Orchestrator::new();
// Register pages
app.register(MyPage::Home { counter: 0 });
app.register(MyPage::Settings { dark_mode: false });
// Navigate (associated data is ignored for lookup)
app.navigate_to(MyPage::Home { counter: 999 }).unwrap();
Capacity Configuration (no_std)
In no_std mode without alloc, configure capacities via const generics:
// Orchestrator<Page, PAGES, HISTORY, FOCUS, BINDINGS, MODES, EVENTS>
let mut app: Orchestrator<MyPage, 8, 16, 16, 32, 8, 8> = Orchestrator::new();
| Generic | Default | Description |
|---|---|---|
PAGES |
8 | Maximum registered pages |
HISTORY |
16 | Navigation history depth |
FOCUS |
16 | Focus targets per page |
BINDINGS |
32 | Key bindings |
MODES |
8 | Mode stack depth |
EVENTS |
8 | Pending event buffer |
With alloc, these limits don't apply.
API Differences
process_frame Return Type
// With alloc: returns Vec<Event>
let events: Vec<MyEvent> = app.process_frame(key)?;
// Without alloc: returns Option<Event>
let event: Option<MyEvent> = app.process_frame(key)?;
EventBus
// With alloc: register handlers via Box<dyn EventHandler>
app.event_bus_mut().register(Box::new(my_handler));
// Without alloc: poll pending events
for event in app.event_bus_mut().drain() {
// handle event
}
Custom Handlers (alloc only)
#[cfg(feature = "alloc")]
{
app.set_action_resolver(MyResolver);
app.set_command_handler(MyHandler);
app.set_state_coordinator(MyCoordinator);
}
License
MIT OR Apache-2.0
Description
Languages
Rust
98.2%
Nix
1.8%