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 { surface_id: surface_id.into(), path: None, value: None }
32 }
33
34 pub fn path(mut self, path: impl Into<String>) -> Self {
35 self.path = Some(path.into());
36 self
37 }
38
39 pub fn value(mut self, value: DataModelValue) -> Self {
40 self.value = match value {
41 DataModelValue::Null => Some(Value::Null),
42 DataModelValue::Json(v) => Some(v),
43 };
44 self
45 }
46
47 pub fn build(self) -> A2uiMessage {
48 A2uiMessage::UpdateDataModel(UpdateDataModelMessage {
49 update_data_model: UpdateDataModel {
50 surface_id: self.surface_id,
51 path: self.path,
52 value: self.value,
53 },
54 })
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61 use serde_json::json;
62
63 #[test]
64 fn builds_update_data_model_message() {
65 let message = UpdateDataModelBuilder::new("main")
66 .path("/user")
67 .value(DataModelValue::Json(json!({"name": "Alice"})))
68 .build();
69
70 let value = serde_json::to_value(&message).unwrap();
71 assert_eq!(value["updateDataModel"]["surfaceId"], "main");
72 assert_eq!(value["updateDataModel"]["path"], "/user");
73 }
74}