Skip to main content

aft/lsp/
jsonrpc.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4/// JSON-RPC request ID.
5#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
6#[serde(untagged)]
7pub enum RequestId {
8    Int(i64),
9    String(String),
10}
11
12/// Outgoing JSON-RPC request.
13#[derive(Debug, Serialize)]
14pub struct Request {
15    pub jsonrpc: &'static str,
16    pub id: RequestId,
17    pub method: String,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub params: Option<Value>,
20}
21
22impl Request {
23    pub fn new(id: RequestId, method: impl Into<String>, params: Option<Value>) -> Self {
24        Self {
25            jsonrpc: "2.0",
26            id,
27            method: method.into(),
28            params,
29        }
30    }
31}
32
33/// Outgoing JSON-RPC notification (no id).
34#[derive(Debug, Serialize)]
35pub struct Notification {
36    pub jsonrpc: &'static str,
37    pub method: String,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub params: Option<Value>,
40}
41
42impl Notification {
43    pub fn new(method: impl Into<String>, params: Option<Value>) -> Self {
44        Self {
45            jsonrpc: "2.0",
46            method: method.into(),
47            params,
48        }
49    }
50}
51
52/// Incoming JSON-RPC response.
53#[derive(Debug, Deserialize)]
54pub struct Response {
55    pub id: RequestId,
56    pub result: Option<Value>,
57    pub error: Option<ResponseError>,
58}
59
60#[derive(Debug, Deserialize)]
61pub struct ResponseError {
62    pub code: i32,
63    pub message: String,
64    pub data: Option<Value>,
65}
66
67/// Outgoing JSON-RPC response (for responding to server requests).
68#[derive(Debug, Serialize)]
69pub struct OutgoingResponse {
70    pub jsonrpc: &'static str,
71    pub id: RequestId,
72    pub result: Value,
73}
74
75impl OutgoingResponse {
76    /// Create a success response with the given result.
77    pub fn success(id: RequestId, result: Value) -> Self {
78        Self {
79            jsonrpc: "2.0",
80            id,
81            result,
82        }
83    }
84}
85
86/// Any incoming message from the server.
87#[derive(Debug)]
88pub enum ServerMessage {
89    Response(Response),
90    Notification {
91        method: String,
92        params: Option<Value>,
93    },
94    Request {
95        id: RequestId,
96        method: String,
97        params: Option<Value>,
98    },
99}
100
101impl ServerMessage {
102    pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
103        let value: Value = serde_json::from_str(json)?;
104
105        if value.get("id").is_some() && value.get("method").is_some() {
106            Ok(ServerMessage::Request {
107                id: serde_json::from_value(value.get("id").cloned().unwrap_or(Value::Null))?,
108                method: value
109                    .get("method")
110                    .and_then(Value::as_str)
111                    .unwrap_or_default()
112                    .to_string(),
113                params: value.get("params").cloned(),
114            })
115        } else if value.get("id").is_some() {
116            Ok(ServerMessage::Response(serde_json::from_value(value)?))
117        } else {
118            Ok(ServerMessage::Notification {
119                method: value
120                    .get("method")
121                    .and_then(Value::as_str)
122                    .unwrap_or_default()
123                    .to_string(),
124                params: value.get("params").cloned(),
125            })
126        }
127    }
128}