Skip to main content

lsp_max/jsonrpc/
response.rs

1use std::fmt::{self, Debug, Formatter};
2use std::str::FromStr;
3
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6
7use super::{Error, Id, Result, Version};
8
9#[derive(Clone, PartialEq, Deserialize, Serialize)]
10#[serde(untagged)]
11enum Kind {
12    Ok { result: Value },
13    Err { error: Error },
14}
15
16/// A successful or failed JSON-RPC response.
17#[derive(Clone, PartialEq, Deserialize, Serialize)]
18pub struct Response {
19    jsonrpc: Version,
20    #[serde(flatten)]
21    kind: Kind,
22    id: Id,
23}
24
25impl Response {
26    /// Creates a new successful response from a request ID and `Error` object.
27    pub const fn from_ok(id: Id, result: Value) -> Self {
28        Response {
29            jsonrpc: Version,
30            kind: Kind::Ok { result },
31            id,
32        }
33    }
34
35    /// Creates a new error response from a request ID and `Error` object.
36    pub const fn from_error(id: Id, error: Error) -> Self {
37        Response {
38            jsonrpc: Version,
39            kind: Kind::Err { error },
40            id,
41        }
42    }
43
44    /// Creates a new response from a request ID and either an `Ok(Value)` or `Err(Error)` body.
45    pub fn from_parts(id: Id, body: Result<Value>) -> Self {
46        match body {
47            Ok(result) => Response::from_ok(id, result),
48            Err(error) => Response::from_error(id, error),
49        }
50    }
51
52    /// Splits the response into a request ID paired with either an `Ok(Value)` or `Err(Error)` to
53    /// signify whether the response is a success or failure.
54    pub fn into_parts(self) -> (Id, Result<Value>) {
55        match self.kind {
56            Kind::Ok { result } => (self.id, Ok(result)),
57            Kind::Err { error } => (self.id, Err(error)),
58        }
59    }
60
61    /// Returns `true` if the response indicates success.
62    pub const fn is_ok(&self) -> bool {
63        matches!(self.kind, Kind::Ok { .. })
64    }
65
66    /// Returns `true` if the response indicates failure.
67    pub const fn is_error(&self) -> bool {
68        !self.is_ok()
69    }
70
71    /// Returns the `result` value, if it exists.
72    ///
73    /// This member only exists if the response indicates success.
74    pub const fn result(&self) -> Option<&Value> {
75        match &self.kind {
76            Kind::Ok { result } => Some(result),
77            _ => None,
78        }
79    }
80
81    /// Returns the `error` value, if it exists.
82    ///
83    /// This member only exists if the response indicates failure.
84    pub const fn error(&self) -> Option<&Error> {
85        match &self.kind {
86            Kind::Err { error } => Some(error),
87            _ => None,
88        }
89    }
90
91    /// Returns the corresponding request ID, if known.
92    pub const fn id(&self) -> &Id {
93        &self.id
94    }
95
96    /// Constructs a JSON-RPC response from an `lsp_types_max::ResponseMessage`.
97    pub fn from_message(msg: lsp_types_max::ResponseMessage) -> Self {
98        match msg {
99            lsp_types_max::ResponseMessage::Success { id, result, .. } => {
100                Response::from_ok(id.map(Id::from).unwrap_or(Id::Null), result)
101            }
102            lsp_types_max::ResponseMessage::Error { id, error, .. } => Response::from_error(
103                id.map(Id::from).unwrap_or(Id::Null),
104                Error {
105                    code: (error.code as i64).into(),
106                    message: std::borrow::Cow::Owned(error.message),
107                    data: error.data,
108                },
109            ),
110        }
111    }
112}
113
114impl Debug for Response {
115    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
116        let mut d = f.debug_struct("Response");
117        d.field("jsonrpc", &self.jsonrpc);
118
119        match &self.kind {
120            Kind::Ok { result } => d.field("result", result),
121            Kind::Err { error } => d.field("error", error),
122        };
123
124        d.field("id", &self.id).finish()
125    }
126}
127
128impl FromStr for Response {
129    type Err = serde_json::Error;
130
131    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
132        serde_json::from_str(s)
133    }
134}