Files
pages-tui/README.md
2026-01-19 15:58:44 +01:00

144 lines
3.3 KiB
Markdown

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
```toml
[dependencies]
pages-tui = "0.2"
```
No allocator needed! Uses `heapless` collections with const generic capacities.
### With Allocation
```toml
[dependencies]
pages-tui = { version = "0.2", features = ["alloc"] }
```
Uses `Vec`, `Box`, `HashMap` for dynamic sizing and trait objects.
### With Full Std
```toml
[dependencies]
pages-tui = { version = "0.2", features = ["std"] }
```
## Usage
Define your page as an enum that implements the `Page` trait:
```rust
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:
```rust
// 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
```rust
// 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
```rust
// 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)
```rust
#[cfg(feature = "alloc")]
{
app.set_action_resolver(MyResolver);
app.set_command_handler(MyHandler);
app.set_state_coordinator(MyCoordinator);
}
```
## License
MIT OR Apache-2.0