1use crate::error::{Error, Result};
27use crate::messages::{Event, Request, Response};
28use serde::{Deserialize, Serialize};
29
30pub struct Protocol;
32
33impl Protocol {
34 pub fn serialize<T: Serialize>(message: &T) -> Result<String> {
36 let json = serde_json::to_string(message)?;
37 Ok(format!("{}\n", json))
38 }
39
40 pub fn deserialize<T: for<'de> Deserialize<'de>>(line: &str) -> Result<T> {
42 let trimmed = line.trim();
43 if trimmed.is_empty() {
44 return Err(Error::Protocol("Empty line".to_string()));
45 }
46 Ok(serde_json::from_str(trimmed)?)
47 }
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
52#[serde(tag = "message_class", rename_all = "snake_case")]
53pub enum MessageEnvelope {
54 Request(Request),
55 Response(Response),
56 Event(Event),
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use crate::messages::*;
63
64 #[test]
65 fn test_serialize_deserialize() {
66 let request = Request {
67 message_type: "request".to_string(),
68 id: "test-123".to_string(),
69 session_id: Some("session-456".to_string()),
70 payload: RequestPayload::Initialize(InitializeRequest {
71 working_directory: Some("/home/user".to_string()),
72 environment: None,
73 capabilities: None,
74 }),
75 metadata: None,
76 };
77
78 let serialized = Protocol::serialize(&request).unwrap();
79 assert!(serialized.ends_with('\n'));
80
81 let deserialized: Request = Protocol::deserialize(&serialized).unwrap();
82 assert_eq!(deserialized.id, request.id);
83 }
84
85 #[test]
86 fn test_empty_line_error() {
87 let result: Result<Request> = Protocol::deserialize("");
88 assert!(result.is_err());
89 }
90
91 #[test]
92 fn test_invalid_json_error() {
93 let result: Result<Request> = Protocol::deserialize("not valid json");
94 assert!(result.is_err());
95 }
96}