tower_lsp_server/jsonrpc/
response.rs

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