opencore_jsonrpc_rust/
protocol.rs1use serde::{Deserialize, Serialize};
7use serde_json::Value;
8
9#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
27pub struct Request {
28 pub id: String,
29 pub action: String,
30 pub params: Vec<Value>,
31}
32
33#[derive(Debug, Serialize, Clone, PartialEq)]
62#[serde(tag = "status")]
63pub enum Response {
64 #[serde(rename = "ok")]
66 Ok {
67 id: String,
69 result: Value,
71 },
72
73 #[serde(rename = "error")]
75 Error {
76 id: String,
78 error: String,
80 },
81}
82
83#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
85pub struct Event {
86 #[serde(rename = "type")]
88 pub kind: String,
89 pub event: String,
91 #[serde(skip_serializing_if = "Option::is_none")]
93 pub data: Option<Value>,
94}
95
96impl Event {
97 pub fn new(event: impl Into<String>, data: Option<Value>) -> Self {
99 Self {
100 kind: "event".to_string(),
101 event: event.into(),
102 data,
103 }
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110 use serde_json::json;
111
112 #[test]
113 fn test_request_deserialization() {
114 let json_str = r#"{"id":"req-123","action":"sum","params":[5,10]}"#;
115 let req: Request = serde_json::from_str(json_str).unwrap();
116
117 assert_eq!(req.id, "req-123");
118 assert_eq!(req.action, "sum");
119 assert_eq!(req.params.len(), 2);
120 assert_eq!(req.params[0], json!(5));
121 assert_eq!(req.params[1], json!(10));
122 }
123
124 #[test]
125 fn test_request_with_empty_params() {
126 let json_str = r#"{"id":"req-456","action":"ping","params":[]}"#;
127 let req: Request = serde_json::from_str(json_str).unwrap();
128
129 assert_eq!(req.id, "req-456");
130 assert_eq!(req.action, "ping");
131 assert_eq!(req.params.len(), 0);
132 }
133
134 #[test]
135 fn test_response_ok_serialization() {
136 let response = Response::Ok {
137 id: "req-123".to_string(),
138 result: json!(15),
139 };
140
141 let json_str = serde_json::to_string(&response).unwrap();
142 let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
143
144 assert_eq!(parsed["status"], "ok");
145 assert_eq!(parsed["id"], "req-123");
146 assert_eq!(parsed["result"], 15);
147 }
148
149 #[test]
150 fn test_response_error_serialization() {
151 let response = Response::Error {
152 id: "req-456".to_string(),
153 error: "Invalid parameters".to_string(),
154 };
155
156 let json_str = serde_json::to_string(&response).unwrap();
157 let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
158
159 assert_eq!(parsed["status"], "error");
160 assert_eq!(parsed["id"], "req-456");
161 assert_eq!(parsed["error"], "Invalid parameters");
162 }
163
164 #[test]
165 fn test_request_clone() {
166 let req = Request {
167 id: "req-789".to_string(),
168 action: "test".to_string(),
169 params: vec![json!(1), json!(2)],
170 };
171
172 let cloned = req.clone();
173 assert_eq!(req, cloned);
174 }
175
176 #[test]
177 fn test_response_clone() {
178 let response = Response::Ok {
179 id: "req-999".to_string(),
180 result: json!("success"),
181 };
182
183 let cloned = response.clone();
184 assert_eq!(response, cloned);
185 }
186
187 #[test]
188 fn test_event_serialization() {
189 let event = Event::new("worker.ready", Some(json!({"pid": 42})));
190
191 let json_str = serde_json::to_string(&event).unwrap();
192 let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
193
194 assert_eq!(parsed["type"], "event");
195 assert_eq!(parsed["event"], "worker.ready");
196 assert_eq!(parsed["data"]["pid"], 42);
197 }
198
199 #[test]
200 fn test_event_without_data_serialization() {
201 let event = Event::new("heartbeat", None);
202
203 let json_str = serde_json::to_string(&event).unwrap();
204 let parsed: serde_json::Value = serde_json::from_str(&json_str).unwrap();
205
206 assert_eq!(parsed["type"], "event");
207 assert_eq!(parsed["event"], "heartbeat");
208 assert!(parsed.get("data").is_none());
209 }
210}