1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! TEA (The Elm Architecture) application framework.
//!
//! This module provides a structured way to build TUI applications using
//! the Elm-inspired unidirectional data flow pattern:
//!
//! ```text
//! ┌─────────────────────────────────────────────────────────┐
//! │ Application │
//! │ │
//! │ ┌─────────┐ ┌────────┐ ┌──────────────────┐ │
//! │ │ State │────▶│ View │────▶│ Terminal/Frame │ │
//! │ └─────────┘ └────────┘ └──────────────────┘ │
//! │ ▲ │
//! │ │ │
//! │ ┌─────────┐ ┌────────────────────┐ │
//! │ │ Update │◀────│ Message/Events │ │
//! │ └─────────┘ └────────────────────┘ │
//! │ │ ▲ │
//! │ ▼ │ │
//! │ ┌─────────┐ ┌────────────────────┐ │
//! │ │ Effects │────▶│ Effect Handler │ │
//! │ └─────────┘ └────────────────────┘ │
//! └─────────────────────────────────────────────────────────┘
//! ```
//!
//! # Core Concepts
//!
//! - **State**: The complete application state (should be serializable)
//! - **Message**: Discrete events that can change state
//! - **Update**: Pure function: `(state, message) → (state, effects)`
//! - **View**: Pure function: `state → UI`
//! - **Effect**: Side effects to execute (IO, commands, etc.)
//!
//! # State Initialization
//!
//! [`App::init`] takes [`App::Args`] — an associated type per impl — and returns
//! the initial state plus any startup command. Apps that need no injected
//! config declare `type Args = ();`; apps that need CLI arguments, config
//! files, opened resources, or test fixtures declare a custom `Args` type
//! and pass values via [`RuntimeBuilder::with_args`].
//!
//! - **No-args apps** (`type Args = ()`): chain `.build()` directly on the
//! builder; the no-args path is gated by the sealed [`OptionalArgs`]
//! marker, which is implemented only for `()`.
//!
//! - **Args apps**: call `.with_args(args)` before `.build()`. This consumes
//! the [`RuntimeBuilder`] and returns a [`ConfiguredRuntimeBuilder`] whose
//! `build()` is unconditionally available. Any prior config-shaping calls
//! (`tick_rate`, `frame_rate`, etc.) are preserved across the promotion.
//!
//! Forgetting `.with_args(...)` for a non-`()` Args type is a compile error,
//! not a runtime panic — `RuntimeBuilder::build()` is only in scope when
//! `A::Args: OptionalArgs`.
//!
//! [`Runtime::terminal_builder()`]: Runtime::terminal_builder
//! [`Runtime::virtual_builder()`]: Runtime::virtual_builder
//! [`RuntimeBuilder::with_args`]: RuntimeBuilder::with_args
//!
//! # Example
//!
//! ```rust
//! use envision::app::{App, Command, Update};
//! use envision::input::Event;
//! use ratatui::Frame;
//!
//! // Define your state
//! #[derive(Default, Clone)]
//! struct CounterState {
//! count: i32,
//! }
//!
//! // Define your messages
//! #[derive(Clone)]
//! enum CounterMsg {
//! Increment,
//! Decrement,
//! Reset,
//! }
//!
//! // Implement the App trait
//! struct CounterApp;
//!
//! impl App for CounterApp {
//! type State = CounterState;
//! type Message = CounterMsg;
//! type Args = ();
//!
//! fn init(_args: ()) -> (Self::State, Command<Self::Message>) {
//! (CounterState::default(), Command::none())
//! }
//!
//! fn update(state: &mut Self::State, msg: Self::Message) -> Command<Self::Message> {
//! match msg {
//! CounterMsg::Increment => state.count += 1,
//! CounterMsg::Decrement => state.count -= 1,
//! CounterMsg::Reset => state.count = 0,
//! }
//! Command::none()
//! }
//!
//! fn view(state: &Self::State, frame: &mut Frame) {
//! // Render the UI based on state
//! }
//! }
//! ```
pub use ;
pub use ;
pub use load_state;
pub use restore_terminal;
pub use ;
pub use ;
pub use ;