1use serde_json::Value;
2
3#[derive(Debug, Clone)]
4pub enum Direction {
5 ToClient,
6 ToServer,
7}
8
9#[derive(Debug, Clone)]
10pub struct Request {
11 pub id: i64,
12 pub method: String,
13 pub params: Option<Value>,
14}
15
16#[derive(Debug, Clone)]
17pub struct Response {
18 pub id: i64,
19 pub result: Option<Value>,
20 pub error: Option<Value>,
21}
22
23#[derive(Debug, Clone)]
24pub struct Notification {
25 pub method: String,
26 pub params: Option<Value>,
27}
28
29#[derive(Debug, Clone)]
30pub enum Message {
31 Request(Request),
32 Response(Response),
33 Notification(Notification),
34}
35
36impl Message {
37 pub fn from_value(value: Value) -> Result<Self, String> {
38 let obj = value.as_object().ok_or("Message must be an object")?;
39
40 let id = obj.get("id").and_then(|id| id.as_i64());
41 let method = obj.get("method").and_then(|m| m.as_str()).map(String::from);
42 let params = obj.get("params").cloned();
43 let result = obj.get("result").cloned();
44 let error = obj.get("error").cloned();
45
46 match (id, method, result.is_some() || error.is_some()) {
47 (Some(id), Some(method), false) => Ok(Message::Request(Request { id, method, params })),
48 (Some(id), None, true) => Ok(Message::Response(Response { id, result, error })),
49 (None, Some(method), false) => {
50 Ok(Message::Notification(Notification { method, params }))
51 }
52 _ => Err("Invalid message format".to_string()),
53 }
54 }
55
56 pub fn to_value(&self) -> Value {
57 match self {
58 Message::Request(Request { id, method, params }) => {
59 let mut obj = serde_json::json!({
60 "jsonrpc": "2.0",
61 "id": id,
62 "method": method,
63 });
64 if let Some(params) = params {
65 obj["params"] = params.clone();
66 }
67 obj
68 }
69 Message::Response(Response { id, result, error }) => {
70 let mut obj = serde_json::json!({
71 "jsonrpc": "2.0",
72 "id": id,
73 });
74 if let Some(result) = result {
75 obj["result"] = result.clone();
76 }
77 if let Some(error) = error {
78 obj["error"] = error.clone();
79 }
80 obj
81 }
82 Message::Notification(Notification { method, params }) => {
83 let mut obj = serde_json::json!({
84 "jsonrpc": "2.0",
85 "method": method,
86 });
87 if let Some(params) = params {
88 obj["params"] = params.clone();
89 }
90 obj
91 }
92 }
93 }
94
95 pub fn get_method(&self) -> Option<&str> {
96 match self {
97 Message::Request(Request { method, .. }) => Some(method),
98 Message::Response(Response { .. }) => None,
99 Message::Notification(Notification { method, .. }) => Some(method),
100 }
101 }
102
103 pub fn get_id(&self) -> Option<&i64> {
104 match self {
105 Message::Request(Request { id, .. }) => Some(id),
106 Message::Response(Response { id, .. }) => Some(id),
107 Message::Notification(Notification { .. }) => None,
108 }
109 }
110
111 pub fn notification(method: &str, params: Option<Value>) -> Self {
112 Message::Notification(Notification {
113 method: method.to_owned(),
114 params,
115 })
116 }
117}