Skip to main content

a2ui_types/v10/
common_types.rs

1use serde::{Deserialize, Serialize};
2
3use crate::common::ComponentId;
4
5// ---------------------------------------------------------------------------
6// Data binding & function call — the core of v1.0 dynamic values
7// ---------------------------------------------------------------------------
8
9/// A data binding reference to the data model via JSON Pointer.
10///
11/// Serialized as `{"@path": "..."}`. The `@` prefix marks the key as part of the
12/// protocol's reserved system namespace.
13#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
14#[serde(deny_unknown_fields)]
15pub struct DataBinding {
16    /// A JSON Pointer path to a value in the data model.
17    #[serde(rename = "@path")]
18    pub path: String,
19}
20
21/// Invokes a named function on the client.
22///
23/// Serialized as `{"@call": "...", "catalogId": "...", "args": {...}}`.
24#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
25#[serde(deny_unknown_fields)]
26pub struct FunctionCall {
27    /// The name of the function to call.
28    #[serde(rename = "@call")]
29    pub call: String,
30
31    /// The catalog ID defining the function, overriding any surface default.
32    #[serde(rename = "catalogId", skip_serializing_if = "Option::is_none")]
33    pub catalog_id: Option<String>,
34
35    /// Arguments passed to the function.
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub args: Option<serde_json::Value>,
38}
39
40// ---------------------------------------------------------------------------
41// Dynamic value types
42// ---------------------------------------------------------------------------
43
44/// A string that can be a literal, a data binding, or a function call returning a string.
45#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
46#[serde(untagged)]
47pub enum DynamicString {
48    Literal(String),
49    Binding(DataBinding),
50    Function(FunctionCall),
51}
52
53/// A number that can be literal, data-bound, or a function call.
54#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
55#[serde(untagged)]
56pub enum DynamicNumber {
57    Literal(f64),
58    Binding(DataBinding),
59    Function(FunctionCall),
60}
61
62/// A boolean that can be literal, data-bound, or a function call.
63#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
64#[serde(untagged)]
65pub enum DynamicBoolean {
66    Literal(bool),
67    Binding(DataBinding),
68    Function(FunctionCall),
69}
70
71/// A string list that can be literal, data-bound, or a function call.
72#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
73#[serde(untagged)]
74pub enum DynamicStringList {
75    Literal(Vec<String>),
76    Binding(DataBinding),
77    Function(FunctionCall),
78}
79
80/// A value that can be any literal, a data binding, or a function call.
81#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
82#[serde(untagged)]
83pub enum DynamicValue {
84    String(String),
85    Number(f64),
86    Bool(bool),
87    Array(Vec<serde_json::Value>),
88    Binding(DataBinding),
89    Function(FunctionCall),
90    Object(serde_json::Value),
91}
92
93// ---------------------------------------------------------------------------
94// Child list — how containers hold children
95// ---------------------------------------------------------------------------
96
97/// A template for generating children from a data model list.
98#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
99#[serde(deny_unknown_fields)]
100pub struct ChildListTemplate {
101    /// The component to use as a template for each item.
102    #[serde(rename = "componentId")]
103    pub component_id: ComponentId,
104
105    /// The path to the list in the data model.
106    pub path: String,
107}
108
109/// Defines how a container holds its children.
110/// Either a static array of component IDs, or a template for dynamic lists.
111#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
112#[serde(untagged)]
113pub enum ChildList {
114    Static(Vec<ComponentId>),
115    Template(ChildListTemplate),
116}
117
118// ---------------------------------------------------------------------------
119// Actions
120// ---------------------------------------------------------------------------
121
122/// An event to dispatch to the agent.
123#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
124#[serde(deny_unknown_fields)]
125pub struct ActionEvent {
126    /// The name of the action to dispatch.
127    pub name: String,
128
129    /// Optional human-readable description of the action performed.
130    #[serde(rename = "userMessage", skip_serializing_if = "Option::is_none")]
131    pub user_message: Option<DynamicString>,
132
133    /// Key-value pairs for the action context.
134    #[serde(skip_serializing_if = "Option::is_none")]
135    pub context: Option<serde_json::Value>,
136}
137
138/// Defines an interaction handler: either an agent-side event or a local function call.
139#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
140#[serde(untagged)]
141pub enum Action {
142    Event {
143        #[serde(rename = "event")]
144        event: ActionEvent,
145    },
146    FunctionCall {
147        #[serde(rename = "functionCall")]
148        function_call: FunctionCall,
149    },
150}
151
152// ---------------------------------------------------------------------------
153// Checks / Validation
154// ---------------------------------------------------------------------------
155
156/// The condition of a validation check: a data binding or a function call
157/// that evaluates to a structured validation result.
158#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
159#[serde(untagged)]
160pub enum CheckCondition {
161    Binding(DataBinding),
162    Function(FunctionCall),
163}
164
165/// A single validation rule applied to an input component.
166#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
167#[serde(deny_unknown_fields)]
168pub struct CheckRule {
169    /// The condition to evaluate.
170    pub condition: CheckCondition,
171
172    /// Optional fallback error message to display if the check fails.
173    #[serde(skip_serializing_if = "Option::is_none")]
174    pub message: Option<String>,
175}
176
177/// A structured validation result returned by a check condition.
178#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
179pub struct ValidationResult {
180    /// Whether the check passed.
181    pub valid: bool,
182
183    /// Machine-readable error code (e.g. `EXPIRED_CARD`).
184    #[serde(skip_serializing_if = "Option::is_none")]
185    pub code: Option<String>,
186
187    /// Human-readable error or warning message.
188    #[serde(skip_serializing_if = "Option::is_none")]
189    pub message: Option<String>,
190
191    /// Severity level of the validation result.
192    #[serde(skip_serializing_if = "Option::is_none")]
193    pub severity: Option<ValidationSeverity>,
194}
195
196/// Severity level of a validation result.
197#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
198#[serde(rename_all = "lowercase")]
199pub enum ValidationSeverity {
200    Error,
201    Warning,
202    Info,
203}
204
205// ---------------------------------------------------------------------------
206// Accessibility
207// ---------------------------------------------------------------------------
208
209/// Attributes for assistive technologies.
210#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
211pub struct AccessibilityAttributes {
212    /// A short label for the element.
213    #[serde(skip_serializing_if = "Option::is_none")]
214    pub label: Option<DynamicString>,
215
216    /// Additional description for the element.
217    #[serde(skip_serializing_if = "Option::is_none")]
218    pub description: Option<DynamicString>,
219
220    /// Controls screen-reader announcements for dynamic updates.
221    #[serde(skip_serializing_if = "Option::is_none")]
222    pub live: Option<AccessibilityLive>,
223
224    /// Hides the element from assistive technologies when true.
225    #[serde(skip_serializing_if = "Option::is_none")]
226    pub hidden: Option<DynamicBoolean>,
227}
228
229/// Screen-reader announcement mode for dynamic updates.
230#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
231#[serde(rename_all = "lowercase")]
232pub enum AccessibilityLive {
233    Off,
234    Polite,
235    Assertive,
236}
237
238// ---------------------------------------------------------------------------
239// Function responses
240// ---------------------------------------------------------------------------
241
242/// An error reported when a function call fails.
243#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
244#[serde(deny_unknown_fields)]
245pub struct FunctionError {
246    /// Machine-readable error code.
247    pub code: String,
248
249    /// Human-readable description of the failure.
250    pub message: String,
251}
252
253/// The return response matching a `callAgentFunction` or `callRendererFunction` invocation.
254#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
255pub struct FunctionResponse {
256    /// The unique ID matching the initiating function call.
257    #[serde(rename = "functionCallId")]
258    pub function_call_id: String,
259
260    /// The returned execution value.
261    #[serde(skip_serializing_if = "Option::is_none")]
262    pub value: Option<serde_json::Value>,
263
264    /// An error object indicating execution failure.
265    #[serde(skip_serializing_if = "Option::is_none")]
266    pub error: Option<FunctionError>,
267}