//! Events fed into the application's update function. //! //! `AppEvent` is the single input type the runtime delivers to //! `App::update`. Synthetic instances drive Tier 3 integration //! tests (see ADR-0008), so the type is plain data with no //! runtime dependency. use crossterm::event::KeyEvent; use crate::db::{ AddColumnResult, ChangeColumnTypeResult, DataResult, DbError, DeleteResult, DropColumnResult, InsertResult, QueryPlan, RelationshipDiagramData, TableDescription, UpdateResult, }; use crate::dsl::Command; #[derive(Debug, Clone)] pub enum AppEvent { Key(KeyEvent), Resize { cols: u16, rows: u16, }, Tick, /// A DSL command finished successfully. `description` is /// `Some` for commands that produce a table view (create, /// add column) and `None` for commands that don't (drop). DslSucceeded { command: Command, description: Option, /// The DSL → SQL teaching echo (ADR-0038): equivalent advanced-mode /// SQL, built by the runtime when a DSL-form command ran in an /// advanced effective mode (ADR-0037). `None` when no echo applies /// (simple mode, SQL-entered, or a form with no echo). The App /// renders it beneath `[ok]`. echo: Option>, }, /// A SQL `CREATE TABLE IF NOT EXISTS` matched an existing table — /// a no-op (ADR-0035 §4). Renders the existing structure plus an /// "already exists — skipped" note. DslCreateSkipped { command: Command, description: TableDescription, }, /// A SQL `DROP TABLE IF EXISTS` matched no table — a no-op /// (ADR-0035 §4, 4c). Renders a "doesn't exist — skipped" note; /// there is no structure to show. DslDropSkipped { command: Command, }, /// A SQL `DROP INDEX IF EXISTS` matched no index — a no-op /// (ADR-0035 §4d). Renders an index-specific "doesn't exist — /// skipped" note; no structure to show. DslDropIndexSkipped { command: Command, }, /// A SQL `CREATE INDEX IF NOT EXISTS` matched an existing index name /// — a no-op (ADR-0035 §4d). `name` is the resolved index name (the /// auto-name is not on the command). Renders "already exists — /// skipped"; no structure to show. DslCreateIndexSkipped { command: Command, name: String, }, /// A `show data` query succeeded. `echo` is the DSL → SQL teaching /// echo (ADR-0038) — built post-execution because the limited form /// orders by the table's primary key (handoff §5). `None` for a /// SQL-entered `SELECT` or any simple-mode submission. DslDataSucceeded { command: Command, data: DataResult, echo: Option>, }, /// An `explain …` command succeeded (ADR-0028). `plan` /// carries the captured query plan; nothing was executed. DslExplainSucceeded { command: Command, plan: QueryPlan }, /// A `show ` list command (V5) — carries pre-formatted /// display lines (tables / relationships / indexes). DslShowListSucceeded { command: Command, lines: Vec }, /// `show relationship ` (ADR-0044) — structured data for the /// diagram, rendered App-side; `None` when no such relationship. DslShowRelationshipSucceeded { command: Command, data: Option, }, DslInsertSucceeded { command: Command, result: InsertResult, }, DslSeedSucceeded { command: Command, result: crate::db::SeedResult, }, DslUpdateSucceeded { command: Command, result: UpdateResult, /// The DSL → SQL teaching echo (ADR-0038): `UPDATE T SET …` for an /// `update … --all-rows` fall-through. `None` for a SQL-entered /// `UPDATE` or any simple-mode submission. echo: Option>, }, DslDeleteSucceeded { command: Command, result: DeleteResult, /// The DSL → SQL teaching echo (ADR-0038): `DELETE FROM T` for a /// `delete … --all-rows` fall-through. `None` for a SQL-entered /// `DELETE` or any simple-mode submission. echo: Option>, }, /// A `change column …` succeeded. `result` carries both the /// post-rebuild description (for the auto-show) and the /// optional `[client-side]` note (ADR-0017 §6). DslChangeColumnSucceeded { command: Command, result: ChangeColumnTypeResult, /// The DSL → SQL teaching echo (ADR-0038): `ALTER TABLE T ALTER /// COLUMN c SET DATA TYPE …`. `None` in simple mode. echo: Option>, /// The `--dont-convert` caveat (ADR-0038 §6 category 3): set by the /// runtime to `true` when the command ran with /// `ChangeColumnMode::DontConvert` in an advanced effective mode /// (the only case where it is meaningful — the line references /// "the line above," i.e. the echo). The App renders the prose /// caveat between the existing client-side notes and the structure. dont_convert_caveat: bool, }, /// An `add column …` succeeded. `result` carries the /// post-add description plus any `[client-side]` notes /// from the auto-fill paths (ADR-0018 §9). DslAddColumnSucceeded { command: Command, result: AddColumnResult, /// The DSL → SQL teaching echo (ADR-0038): `ALTER TABLE T ADD /// COLUMN c …`. `None` in simple mode. echo: Option>, }, /// A `drop column …` succeeded. `result` carries the /// post-drop description plus the names of any indexes /// removed by `--cascade` (ADR-0025). DslDropColumnSucceeded { command: Command, result: DropColumnResult, /// The DSL → SQL teaching echo (ADR-0038): `ALTER TABLE T DROP /// COLUMN c` for a plain (non-`--cascade`) drop. `None` in simple /// mode, and for `--cascade` (a multi-statement echo, Phase 2). echo: Option>, }, /// A DSL command failed. `error` is the structured /// payload, `facts` is the runtime-built schema-resolved /// enrichment (parent tables, attempted values, /// pinpointed offending rows). App applies its current /// verbosity setting (`messages_verbosity`) when rendering /// through `friendly::translate_error` (ADR-0019 §5, §6). DslFailed { command: Command, error: DbError, facts: crate::friendly::FailureContext, /// The original user-typed source line, retained so the /// App can journal the failed command as an `err` record /// (ADR-0034 §1/§2). The worker only journals successful /// commands, so an execution failure would otherwise be /// lost across sessions. source: String, /// Whether the rejected command was submitted in an advanced /// effective mode (ADR-0052): threaded so the App can tag the /// `err` record `err:adv` and the failed advanced command /// hydrates in its `:`-prefixed, simple-mode-recallable form. advanced: bool, }, /// Refreshed list of tables in the database. TablesRefreshed(Vec), /// Refreshed schema lookup cache feeding Tab completion /// for identifier slots (ADR-0022 §9 + stage 8d). Runtime /// posts this alongside `TablesRefreshed` after project /// load and after every successful DDL. SchemaCacheRefreshed(crate::completion::SchemaCache), /// Refreshed list of relationships as full schema records, for the /// sidebar relationships panel (ADR-0046 DB2). Posted by the runtime /// alongside `SchemaCacheRefreshed` after every schema refresh. RelationshipsRefreshed(Vec), /// A persistence failure occurred (ADR-0015 §8). The /// application surfaces a fatal banner and exits cleanly so /// the message remains above the shell prompt. PersistenceFatal { operation: String, path: std::path::PathBuf, message: String, }, /// Runtime has computed the rebuild summary from /// `project.yaml` + `data/` and is ready for the user to /// confirm. App opens the confirmation modal. RebuildPrepared { summary: String, }, /// Rebuild completed successfully. App closes the modal, /// surfaces a friendly outcome message, and refreshes the /// table list. RebuildSucceeded { summary: String, }, /// Rebuild failed in a non-fatal way (e.g., user-visible /// constraint problem) — surfaced like other DSL failures. RebuildFailed { error: String, }, /// Runtime peeked the snapshot `undo`/`redo` would restore and /// is ready for the user to confirm (ADR-0006 Amendment 1). App /// opens the confirmation modal naming `command`. `is_redo` /// selects undo vs redo wording. UndoPrepared { command: String, timestamp: String, is_redo: bool, }, /// Nothing to undo / redo (the ring or redo stack was empty). /// App surfaces a friendly note. UndoUnavailable { is_redo: bool, }, /// Undo / redo completed. App closes the modal, notes the /// command that was undone/redone; the runtime also refreshes /// the table list + schema cache. UndoSucceeded { command: String, is_redo: bool, }, /// Undo / redo failed (a rare restore error). App closes the /// modal and surfaces the error. UndoFailed { error: String, is_redo: bool, }, /// Runtime has gathered the list of available projects /// for the load picker. App opens the picker modal. LoadPickerReady { entries: Vec, }, /// A project switch (load / new / save-as / import) /// succeeded. Carries the new display name, the temp /// flag (drives the `[TEMP]` status-bar prefix), the /// seed entries for input-history hydration off the new /// project's `history.log` (I2-persist, ADR-0015 §12), and /// the mode to restore for the switched-to project (its /// stored mode, ADR-0015 mode-restore amendment, issue #14 — /// "loading triggers the mode switch each time"). ProjectSwitched { display_name: String, is_temp: bool, history_entries: Vec, mode: crate::mode::Mode, }, /// A project switch failed in a non-fatal way (target /// already exists, path unreadable, …). Surfaced as an /// error in the output panel. ProjectSwitchFailed { error: String, }, /// Export wrote a zip successfully. Carries the resolved /// final path so the user gets a "wrote to: …" note. ExportSucceeded { path: std::path::PathBuf, }, /// Export failed in a non-fatal way (target exists, IO /// error, sequence range exhausted, …). ExportFailed { error: String, }, /// A `replay ` finished without error, after running /// `count` non-blank, non-comment commands from the file. /// Surfaced as `[ok] replay — N command(s)` in the output. ReplayCompleted { path: String, count: usize, /// Pre-rendered `[skip]` warnings for app-lifecycle commands /// whose omission can leave the replayed state incomplete — /// `import` and a nested `replay` (ADR-0034). Other skipped /// app commands are silent and do not appear here. warnings: Vec, }, /// A `replay ` aborted at line `line_number`. `command` /// is the line text as it appeared in the file (for the /// user's eyeline so they can locate the failing entry); /// `error` is the rendered parse or runtime error. ReplayFailed { path: String, line_number: usize, command: String, error: String, }, }