a2ui_base/interaction.rs
1//! Framework-agnostic interaction helpers — applying component interaction
2//! results to the runtime state.
3//!
4//! This module holds the parts of the keyboard/interaction pipeline that touch
5//! only core types, so every backend (ratatui, Slint, …) shares them. The
6//! key-mapping and component-dispatch halves stay backend-side: each backend
7//! maps its own key enum to [`crate::event::InputKey`] and dispatches via its
8//! own component registry (or, after the shared-behavior extraction, via
9//! [`crate::components::dispatch_event`]).
10//!
11//! See the tui crate's `interaction` module for the original implementation
12//! this was lifted from.
13
14use crate::event::EventResult;
15use crate::message_processor::MessageProcessor;
16
17/// Apply an [`EventResult`] produced by a component to the processor's state.
18///
19/// Returns `Some(path)` only for an [`EventResult::Action`] that expects a
20/// response — the path is where the eventual server response value should be
21/// written — so the caller can drive the action-response cycle. Every other
22/// variant returns `None`.
23pub fn apply_event_result(processor: &mut MessageProcessor, result: EventResult) -> Option<String> {
24 match result {
25 EventResult::Action {
26 want_response,
27 response_path,
28 // event_name / context are intentionally ignored, matching the gallery.
29 ..
30 } => {
31 if want_response {
32 let surface_id = processor
33 .model
34 .surfaces()
35 .next()
36 .map(|s| s.id.clone());
37 if let Some(sid) = surface_id {
38 let action_id = uuid::Uuid::new_v4().to_string();
39 let _ = processor.register_action(&sid, &action_id, response_path.clone());
40 }
41 response_path
42 } else {
43 None
44 }
45 }
46 EventResult::DataUpdate { path, value } => {
47 if let Some(surface) = processor.model.surfaces_mut().next() {
48 surface.data_model.borrow_mut().set(&path, value);
49 }
50 None
51 }
52 EventResult::Toggle { path } => {
53 if let Some(surface) = processor.model.surfaces_mut().next() {
54 let current = surface
55 .data_model
56 .borrow()
57 .get(&path)
58 .and_then(|v| v.as_bool())
59 .unwrap_or(false);
60 surface
61 .data_model
62 .borrow_mut()
63 .set(&path, serde_json::json!(!current));
64 }
65 None
66 }
67 EventResult::Consumed => None,
68 }
69}