Skip to main content

a2ui_base/model/
surface_model.rs

1//! A single A2UI surface (a distinct UI region).
2
3use std::cell::RefCell;
4use std::collections::HashMap;
5
6use super::components_model::SurfaceComponentsModel;
7use super::data_model::DataModel;
8
9/// Metadata for tracking actions awaiting a server response.
10pub struct PendingAction {
11    /// The unique action ID that was sent to the server.
12    pub action_id: String,
13    /// Optional JSON Pointer path where the response value should be stored.
14    pub response_path: Option<String>,
15}
16
17/// State for a single A2UI surface.
18pub struct SurfaceModel {
19    /// Unique surface identifier.
20    pub id: String,
21    /// Catalog URI this surface uses.
22    pub catalog_id: String,
23    /// Optional surface properties (e.g. agentDisplayName).
24    pub surface_properties: Option<serde_json::Value>,
25    /// Whether to send the full data model with actions.
26    pub send_data_model: bool,
27    /// The data model for this surface.
28    pub data_model: RefCell<DataModel>,
29    /// The component tree for this surface.
30    pub components: RefCell<SurfaceComponentsModel>,
31    /// Actions that are awaiting a server response, keyed by action_id.
32    pub pending_actions: RefCell<HashMap<String, PendingAction>>,
33}
34
35impl SurfaceModel {
36    /// Create a new surface model.
37    pub fn new(
38        id: String,
39        catalog_id: String,
40        surface_properties: Option<serde_json::Value>,
41        send_data_model: bool,
42    ) -> Self {
43        Self {
44            id,
45            catalog_id,
46            surface_properties,
47            send_data_model,
48            data_model: RefCell::new(DataModel::new()),
49            components: RefCell::new(SurfaceComponentsModel::new()),
50            pending_actions: RefCell::new(HashMap::new()),
51        }
52    }
53
54    /// Initialize with a data model value.
55    pub fn with_data_model(mut self, data: serde_json::Value) -> Self {
56        self.data_model = RefCell::new(DataModel::from_value(data));
57        self
58    }
59
60    /// Check if the component tree has a root component.
61    pub fn has_root(&self) -> bool {
62        self.components.borrow().contains("root")
63    }
64}