3use jsonrpc_core as jsonrpc;
5use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
10 io::{AsyncBufRead, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter},
11 process::{ChildStderr, ChildStdin, ChildStdout},
13 mpsc::{unbounded_channel, Sender, UnboundedReceiver, UnboundedSender},
21 chan: Sender<Result<Value>>,
22 value: jsonrpc::MethodCall,
24 Notification(jsonrpc::Notification),
25 Response(jsonrpc::Output),
28/// A type representing all possible values sent from the server to the client.
29#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
30#[serde(deny_unknown_fields)]
33 /// A regular JSON-RPC request output (single response).
34 Output(jsonrpc::Output),
35 /// A JSON-RPC request or notification.
42 pending_requests: Mutex<HashMap<jsonrpc::Id, Sender<Result<Value>>>>,
47 server_stdout: BufReader<ChildStdout>,
48 server_stdin: BufWriter<ChildStdin>,
49 server_stderr: BufReader<ChildStderr>,
52 UnboundedReceiver<(usize, jsonrpc::Call)>,
53 UnboundedSender<Payload>,
55 let (client_tx, rx) = unbounded_channel();
56 let (tx, client_rx) = unbounded_channel();
58 let transport = Self {
60 pending_requests: Mutex::new(HashMap::default()),
63 let transport = Arc::new(transport);
65 tokio::spawn(Self::recv(transport.clone(), server_stdout, client_tx));
66 tokio::spawn(Self::err(transport.clone(), server_stderr));
67 tokio::spawn(Self::send(transport, server_stdin, client_rx));
72 async fn recv_server_message(
73 reader: &mut (impl AsyncBufRead + Unpin + Send),
75 ) -> Result<ServerMessage> {
76 let mut content_length = None;
79 reader.read_line(buffer).await?;
80 let header = buffer.trim();
82 if header.is_empty() {
86 let mut parts = header.split(": ");
88 match (parts.next(), parts.next(), parts.next()) {
89 (Some("Content-Length"), Some(value), None) => {
90 content_length = Some(value.parse().context("invalid content length")?);
92 (Some(_), Some(_), None) => {}
94 return Err(std::io::Error::new(
95 std::io::ErrorKind::Other,
96 "Failed to parse header",
103 let content_length = content_length.context("missing content length")?;
106 let mut content = vec![0; content_length];
107 reader.read_exact(&mut content).await?;
108 let msg = std::str::from_utf8(&content).context("invalid utf8 from server")?;
112 // try parsing as output (server response) or call (server request)
113 let output: serde_json::Result<ServerMessage> = serde_json::from_str(msg);
118 async fn recv_server_error(
119 err: &mut (impl AsyncBufRead + Unpin + Send),
123 err.read_line(buffer).await?;
124 error!("err <- {}", buffer);
129 async fn send_payload_to_server(
131 server_stdin: &mut BufWriter<ChildStdin>,
135 let json = match payload {
136 Payload::Request { chan, value } => {
137 self.pending_requests
140 .insert(value.id.clone(), chan);
141 serde_json::to_string(&value)?
143 Payload::Notification(value) => serde_json::to_string(&value)?,
144 Payload::Response(error) => serde_json::to_string(&error)?,
146 self.send_string_to_server(server_stdin, json).await
149 async fn send_string_to_server(
151 server_stdin: &mut BufWriter<ChildStdin>,
154 info!("-> {}", request);
158 .write_all(format!("Content-Length: {}\r\n\r\n", request.len()).as_bytes())
162 server_stdin.write_all(request.as_bytes()).await?;
164 server_stdin.flush().await?;
169 async fn process_server_message(
171 client_tx: &UnboundedSender<(usize, jsonrpc::Call)>,
175 ServerMessage::Output(output) => self.process_request_response(output).await?,
176 ServerMessage::Call(call) => {
178 .send((self.id, call))
179 .context("failed to send a message to server")?;
180 // let notification = Notification::parse(&method, params);
186 async fn process_request_response(&self, output: jsonrpc::Output) -> Result<()> {
187 let (id, result) = match output {
188 jsonrpc::Output::Success(jsonrpc::Success { id, result, .. }) => {
189 info!("<- {}", result);
192 jsonrpc::Output::Failure(jsonrpc::Failure { id, error, .. }) => {
193 error!("<- {}", error);
194 (id, Err(error.into()))
203 .expect("pending_request with id not found!");
205 match tx.send(result).await {
208 "Tried sending response into a closed channel (id={:?}), original request likely timed out",
217 transport: Arc<Self>,
218 mut server_stdout: BufReader<ChildStdout>,
219 client_tx: UnboundedSender<(usize, jsonrpc::Call)>,
221 let mut recv_buffer = String::new();
223 match Self::recv_server_message(&mut server_stdout, &mut recv_buffer).await {
226 .process_server_message(&client_tx, msg)
231 error!("err: <- {:?}", err);
238 async fn err(_transport: Arc<Self>, mut server_stderr: BufReader<ChildStderr>) {
239 let mut recv_buffer = String::new();
241 match Self::recv_server_error(&mut server_stderr, &mut recv_buffer).await {
244 error!("err: <- {:?}", err);
252 transport: Arc<Self>,
253 mut server_stdin: BufWriter<ChildStdin>,
254 mut client_rx: UnboundedReceiver<Payload>,
256 while let Some(msg) = client_rx.recv().await {
258 .send_payload_to_server(&mut server_stdin, msg)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list