1use serde::{Deserialize, Serialize};
7
8use crate::{DeploymentConfig, DeploymentState, ReleaseInfo};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12#[serde(rename_all = "camelCase")]
13pub struct SyncRequest {
14 pub deployment_id: String,
16 #[serde(skip_serializing_if = "Option::is_none")]
18 pub current_state: Option<DeploymentState>,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
23#[serde(rename_all = "camelCase")]
24pub struct SyncResponse {
25 #[serde(default, skip_serializing_if = "Option::is_none")]
31 pub current_state: Option<DeploymentState>,
32 #[serde(skip_serializing_if = "Option::is_none")]
35 pub target: Option<TargetDeployment>,
36 #[serde(default, skip_serializing_if = "Option::is_none")]
40 pub commands_url: Option<String>,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
45#[serde(rename_all = "camelCase")]
46pub struct TargetDeployment {
47 pub release_info: ReleaseInfo,
49 pub config: DeploymentConfig,
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn test_sync_request_serialization() {
59 let req = SyncRequest {
60 deployment_id: "dep_abc123".to_string(),
61 current_state: None,
62 };
63
64 let json = serde_json::to_value(&req).unwrap();
65 assert_eq!(json["deploymentId"], "dep_abc123");
66 assert!(json.get("currentState").is_none());
68 }
69
70 #[test]
71 fn test_sync_request_deserialization() {
72 let json = r#"{"deploymentId": "dep_xyz"}"#;
73 let req: SyncRequest = serde_json::from_str(json).unwrap();
74 assert_eq!(req.deployment_id, "dep_xyz");
75 assert!(req.current_state.is_none());
76 }
77
78 #[test]
79 fn test_sync_response_empty() {
80 let resp = SyncResponse {
81 current_state: None,
82 target: None,
83 commands_url: None,
84 };
85 let json = serde_json::to_value(&resp).unwrap();
86 assert!(json.get("target").is_none());
88 assert!(json.get("currentState").is_none());
89 }
90
91 #[test]
92 fn test_sync_response_roundtrip_no_target() {
93 let resp = SyncResponse {
94 current_state: None,
95 target: None,
96 commands_url: None,
97 };
98 let serialized = serde_json::to_string(&resp).unwrap();
99 let deserialized: SyncResponse = serde_json::from_str(&serialized).unwrap();
100 assert!(deserialized.target.is_none());
101 assert!(deserialized.current_state.is_none());
102 }
103
104 #[test]
105 fn test_sync_request_with_camel_case() {
106 let json = r#"{"deploymentId": "dep_1", "currentState": null}"#;
108 let req: SyncRequest = serde_json::from_str(json).unwrap();
109 assert_eq!(req.deployment_id, "dep_1");
110 assert!(req.current_state.is_none());
111
112 let json = r#"{"deployment_id": "dep_1"}"#;
114 assert!(serde_json::from_str::<SyncRequest>(json).is_err());
115 }
116}