lapce_rpc/
parse.rs

1use anyhow::{anyhow, Result};
2use serde::de::DeserializeOwned;
3use serde_json::Value;
4
5#[derive(Debug, Clone)]
6pub struct RpcObject(pub Value);
7
8pub type RequestId = u64;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11/// An RPC call, which may be either a notification or a request.
12pub enum Call<N, R> {
13    /// An id and an RPC Request
14    Request(RequestId, R),
15    /// An RPC Notification
16    Notification(N),
17}
18
19impl RpcObject {
20    pub fn get_id(&self) -> Option<RequestId> {
21        self.0.get("id").and_then(Value::as_u64)
22    }
23
24    pub fn is_response(&self) -> bool {
25        self.0.get("id").is_some() && self.0.get("method").is_none()
26    }
27
28    pub fn into_rpc<N, R>(self) -> Result<Call<N, R>>
29    where
30        N: DeserializeOwned,
31        R: DeserializeOwned,
32    {
33        let id = self.get_id();
34        match id {
35            Some(id) => match serde_json::from_value::<R>(self.0) {
36                Ok(resp) => Ok(Call::Request(id, resp)),
37                Err(err) => Err(anyhow!(err)),
38            },
39            None => {
40                let result = serde_json::from_value::<N>(self.0)?;
41                Ok(Call::Notification(result))
42            }
43        }
44    }
45
46    pub fn into_response(mut self) -> Result<Result<Value, Value>, String> {
47        let _ = self
48            .get_id()
49            .ok_or_else(|| "Response requires 'id' field.".to_string())?;
50
51        if self.0.get("result").is_some() == self.0.get("error").is_some() {
52            return Err("RPC response must contain exactly one of\
53                        'error' or 'result' fields."
54                .into());
55        }
56        let result = self.0.as_object_mut().and_then(|obj| obj.remove("result"));
57
58        match result {
59            Some(r) => Ok(Ok(r)),
60            None => {
61                let error = self
62                    .0
63                    .as_object_mut()
64                    .and_then(|obj| obj.remove("error"))
65                    .unwrap();
66                Ok(Err(error))
67            }
68        }
69    }
70}
71
72impl From<Value> for RpcObject {
73    fn from(v: Value) -> RpcObject {
74        RpcObject(v)
75    }
76}