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