tower_lsp/jsonrpc/
request.rs
1use std::borrow::Cow;
2use std::fmt::{self, Display, Formatter};
3use std::str::FromStr;
4
5use serde::{Deserialize, Deserializer, Serialize};
6use serde_json::Value;
7
8use super::{Id, Version};
9
10fn deserialize_some<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
11where
12 T: Deserialize<'de>,
13 D: Deserializer<'de>,
14{
15 T::deserialize(deserializer).map(Some)
16}
17
18#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
20pub struct Request {
21 jsonrpc: Version,
22 #[serde(default)]
23 method: Cow<'static, str>,
24 #[serde(default, deserialize_with = "deserialize_some")]
25 #[serde(skip_serializing_if = "Option::is_none")]
26 params: Option<Value>,
27 #[serde(default, deserialize_with = "deserialize_some")]
28 #[serde(skip_serializing_if = "Option::is_none")]
29 id: Option<Id>,
30}
31
32impl Request {
33 pub fn build<M>(method: M) -> RequestBuilder
37 where
38 M: Into<Cow<'static, str>>,
39 {
40 RequestBuilder {
41 method: method.into(),
42 params: None,
43 id: None,
44 }
45 }
46
47 pub(crate) fn from_request<R>(id: Id, params: R::Params) -> Self
55 where
56 R: lsp_types::request::Request,
57 {
58 Request {
59 jsonrpc: Version,
60 method: R::METHOD.into(),
61 params: Some(serde_json::to_value(params).unwrap()),
62 id: Some(id),
63 }
64 }
65
66 pub(crate) fn from_notification<N>(params: N::Params) -> Self
74 where
75 N: lsp_types::notification::Notification,
76 {
77 Request {
78 jsonrpc: Version,
79 method: N::METHOD.into(),
80 params: Some(serde_json::to_value(params).unwrap()),
81 id: None,
82 }
83 }
84
85 pub fn method(&self) -> &str {
87 self.method.as_ref()
88 }
89
90 pub fn id(&self) -> Option<&Id> {
92 self.id.as_ref()
93 }
94
95 pub fn params(&self) -> Option<&Value> {
97 self.params.as_ref()
98 }
99
100 pub fn into_parts(self) -> (Cow<'static, str>, Option<Id>, Option<Value>) {
102 (self.method, self.id, self.params)
103 }
104}
105
106impl Display for Request {
107 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
108 use std::{io, str};
109
110 struct WriterFormatter<'a, 'b: 'a> {
111 inner: &'a mut Formatter<'b>,
112 }
113
114 impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> {
115 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
116 fn io_error<E>(_: E) -> io::Error {
117 io::Error::new(io::ErrorKind::Other, "fmt error")
120 }
121 let s = str::from_utf8(buf).map_err(io_error)?;
122 self.inner.write_str(s).map_err(io_error)?;
123 Ok(buf.len())
124 }
125
126 fn flush(&mut self) -> io::Result<()> {
127 Ok(())
128 }
129 }
130
131 let mut w = WriterFormatter { inner: f };
132 serde_json::to_writer(&mut w, self).map_err(|_| fmt::Error)
133 }
134}
135
136impl FromStr for Request {
137 type Err = serde_json::Error;
138
139 fn from_str(s: &str) -> Result<Self, Self::Err> {
140 serde_json::from_str(s)
141 }
142}
143
144#[derive(Debug)]
148pub struct RequestBuilder {
149 method: Cow<'static, str>,
150 params: Option<Value>,
151 id: Option<Id>,
152}
153
154impl RequestBuilder {
155 pub fn id<I: Into<Id>>(mut self, id: I) -> Self {
159 self.id = Some(id.into());
160 self
161 }
162
163 pub fn params<V: Into<Value>>(mut self, params: V) -> Self {
167 self.params = Some(params.into());
168 self
169 }
170
171 pub fn finish(self) -> Request {
173 Request {
174 jsonrpc: Version,
175 method: self.method,
176 params: self.params,
177 id: self.id,
178 }
179 }
180}