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, ComponentError> { // Handle actions... Ok(None) } } // Create orchestrator with single generic let mut app: Orchestrator = 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 let mut app: Orchestrator = 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 let events: Vec = app.process_frame(key)?; // Without alloc: returns Option let event: Option = app.process_frame(key)?; ``` ### EventBus ```rust // With alloc: register handlers via Box 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