1use crate::{Error, Event, Result};
3use log::{error, info, warn};
4use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
9 io::{AsyncBufRead, AsyncBufReadExt, AsyncReadExt, AsyncWrite, AsyncWriteExt},
11 mpsc::{unbounded_channel, Sender, UnboundedReceiver, UnboundedSender},
16#[derive(Debug, Clone, Deserialize, Serialize)]
19 pub back_ch: Option<Sender<Result<Response>>>,
22 pub arguments: Option<Value>,
25#[derive(Debug, PartialEq, Clone, Deserialize, Serialize)]
27 // seq is omitted as unused and is not sent by some implementations
31 pub message: Option<String>,
32 pub body: Option<Value>,
35#[derive(Debug, Clone, Deserialize, Serialize)]
36#[serde(tag = "type", rename_all = "camelCase")]
49 pending_requests: Mutex<HashMap<u64, Sender<Result<Response>>>>,
54 server_stdout: Box<dyn AsyncBufRead + Unpin + Send>,
55 server_stdin: Box<dyn AsyncWrite + Unpin + Send>,
57 ) -> (UnboundedReceiver<Payload>, UnboundedSender<Request>) {
58 let (client_tx, rx) = unbounded_channel();
59 let (tx, client_rx) = unbounded_channel();
61 let transport = Self {
63 pending_requests: Mutex::new(HashMap::default()),
66 let transport = Arc::new(transport);
68 tokio::spawn(Self::recv(transport.clone(), server_stdout, client_tx));
69 tokio::spawn(Self::send(transport, server_stdin, client_rx));
74 async fn recv_server_message(
75 reader: &mut Box<dyn AsyncBufRead + Unpin + Send>,
77 ) -> Result<Payload> {
78 let mut content_length = None;
81 reader.read_line(buffer).await?;
82 let header = buffer.trim();
84 if header.is_empty() {
88 let mut parts = header.split(": ");
90 match (parts.next(), parts.next(), parts.next()) {
91 (Some("Content-Length"), Some(value), None) => {
92 content_length = Some(value.parse().context("invalid content length")?);
94 (Some(_), Some(_), None) => {}
96 return Err(std::io::Error::new(
97 std::io::ErrorKind::Other,
98 "Failed to parse header",
105 let content_length = content_length.context("missing content length")?;
108 let mut content = vec![0; content_length];
109 reader.read_exact(&mut content).await?;
110 let msg = std::str::from_utf8(&content).context("invalid utf8 from server")?;
112 info!("<- DAP {}", msg);
114 // try parsing as output (server response) or call (server request)
115 let output: serde_json::Result<Payload> = serde_json::from_str(msg);
120 async fn send_payload_to_server(
122 server_stdin: &mut Box<dyn AsyncWrite + Unpin + Send>,
125 let back_ch = req.back_ch.take();
127 let json = serde_json::to_string(&Payload::Request(req))?;
128 if let Some(back) = back_ch {
129 self.pending_requests.lock().await.insert(seq, back);
131 self.send_string_to_server(server_stdin, json).await
134 async fn send_string_to_server(
136 server_stdin: &mut Box<dyn AsyncWrite + Unpin + Send>,
139 info!("-> DAP {}", request);
143 .write_all(format!("Content-Length: {}\r\n\r\n", request.len()).as_bytes())
147 server_stdin.write_all(request.as_bytes()).await?;
149 server_stdin.flush().await?;
154 fn process_response(res: Response) -> Result<Response> {
156 info!("<- DAP success in response to {}", res.request_seq);
161 "<- DAP error {:?} ({:?}) for command #{} {}",
162 res.message, res.body, res.request_seq, res.command
165 Err(Error::Other(anyhow::format_err!("{:?}", res.body)))
169 async fn process_server_message(
171 client_tx: &UnboundedSender<Payload>,
175 Payload::Response(res) => {
176 let request_seq = res.request_seq;
177 let tx = self.pending_requests.lock().await.remove(&request_seq);
180 Some(tx) => match tx.send(Self::process_response(res)).await {
183 "Tried sending response into a closed channel (id={:?}), original request likely timed out",
188 warn!("Response to nonexistent request #{}", res.request_seq);
189 client_tx.send(Payload::Response(res)).expect("Failed to send");
195 Payload::Request(Request {
200 info!("<- DAP request {} #{}", command, seq);
201 client_tx.send(msg).expect("Failed to send");
204 Payload::Event(ref event) => {
205 info!("<- DAP event {:?}", event);
206 client_tx.send(msg).expect("Failed to send");
213 transport: Arc<Self>,
214 mut server_stdout: Box<dyn AsyncBufRead + Unpin + Send>,
215 client_tx: UnboundedSender<Payload>,
217 let mut recv_buffer = String::new();
219 match Self::recv_server_message(&mut server_stdout, &mut recv_buffer).await {
222 .process_server_message(&client_tx, msg)
227 error!("err: <- {:?}", err);
235 transport: Arc<Self>,
236 mut server_stdin: Box<dyn AsyncWrite + Unpin + Send>,
237 mut client_rx: UnboundedReceiver<Request>,
239 while let Some(req) = client_rx.recv().await {
241 .send_payload_to_server(&mut server_stdin, req)
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