adk_ui/a2ui/
data_model.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4use super::messages::{A2uiMessage, UpdateDataModel, UpdateDataModelMessage};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7#[serde(rename_all = "camelCase")]
8pub struct DataModelUpdate {
9 pub surface_id: String,
10 #[serde(skip_serializing_if = "Option::is_none")]
11 pub path: Option<String>,
12 #[serde(skip_serializing_if = "Option::is_none")]
13 pub value: Option<Value>,
14}
15
16#[derive(Debug, Clone)]
17pub enum DataModelValue {
18 Null,
19 Json(Value),
20}
21
22#[derive(Debug, Default)]
23pub struct UpdateDataModelBuilder {
24 surface_id: String,
25 path: Option<String>,
26 value: Option<Value>,
27}
28
29impl UpdateDataModelBuilder {
30 pub fn new(surface_id: impl Into<String>) -> Self {
31 Self {
32 surface_id: surface_id.into(),
33 path: None,
34 value: None,
35 }
36 }
37
38 pub fn path(mut self, path: impl Into<String>) -> Self {
39 self.path = Some(path.into());
40 self
41 }
42
43 pub fn value(mut self, value: DataModelValue) -> Self {
44 self.value = match value {
45 DataModelValue::Null => Some(Value::Null),
46 DataModelValue::Json(v) => Some(v),
47 };
48 self
49 }
50
51 pub fn build(self) -> A2uiMessage {
52 A2uiMessage::UpdateDataModel(UpdateDataModelMessage::new(UpdateDataModel {
53 surface_id: self.surface_id,
54 path: self.path,
55 value: self.value,
56 }))
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 use serde_json::json;
64
65 #[test]
66 fn builds_update_data_model_message() {
67 let message = UpdateDataModelBuilder::new("main")
68 .path("/user")
69 .value(DataModelValue::Json(json!({"name": "Alice"})))
70 .build();
71
72 let value = serde_json::to_value(&message).unwrap();
73 assert_eq!(value["updateDataModel"]["surfaceId"], "main");
74 assert_eq!(value["updateDataModel"]["path"], "/user");
75 }
76}