1use std::io;
4
5use serde::{Deserialize, Serialize};
6
7pub use dapts::{Event, Request, Response};
8
9use crate::{LspOrDapResponse, invalid_data_fmt, read_msg_text, write_msg_text};
10
11#[derive(Serialize, Deserialize, Debug, Clone)]
13#[serde(tag = "type")]
14pub enum Message {
15 #[serde(rename = "request")]
17 Request(Request),
18 #[serde(rename = "response")]
20 Response(Response),
21 #[serde(rename = "event")]
23 Event(Event),
24}
25
26impl From<Request> for Message {
27 fn from(req: Request) -> Self {
28 Message::Request(req)
29 }
30}
31
32impl From<Response> for Message {
33 fn from(resp: Response) -> Self {
34 Message::Response(resp)
35 }
36}
37
38impl From<Event> for Message {
39 fn from(event: Event) -> Self {
40 Message::Event(event)
41 }
42}
43
44impl Message {
45 pub fn read(r: &mut impl io::BufRead) -> io::Result<Option<Message>> {
47 let text = match read_msg_text(r)? {
48 None => return Ok(None),
49 Some(text) => text,
50 };
51
52 let msg = match serde_json::from_str(&text) {
53 Ok(msg) => msg,
54 Err(e) => {
55 return Err(invalid_data_fmt!("malformed DAP payload: {e:?}"));
56 }
57 };
58
59 Ok(Some(msg))
60 }
61 pub fn write(self, w: &mut impl io::Write) -> io::Result<()> {
63 #[derive(Serialize)]
64 struct JsonRpc {
65 jsonrpc: &'static str,
66 #[serde(flatten)]
67 msg: Message,
68 }
69 let text = serde_json::to_string(&JsonRpc {
70 jsonrpc: "2.0",
71 msg: self,
72 })?;
73 write_msg_text(w, &text)
74 }
75}
76
77impl TryFrom<crate::Message> for Message {
78 type Error = anyhow::Error;
79
80 fn try_from(msg: crate::Message) -> anyhow::Result<Self> {
81 match msg {
82 #[cfg(feature = "lsp")]
83 crate::Message::Lsp(msg) => anyhow::bail!("unexpected LSP message: {msg:?}"),
84 crate::Message::Dap(msg) => Ok(msg),
85 }
86 }
87}
88
89impl From<Request> for crate::Message {
90 fn from(request: Request) -> crate::Message {
91 crate::Message::Dap(request.into())
92 }
93}
94
95impl From<Response> for crate::Message {
96 fn from(response: Response) -> crate::Message {
97 crate::Message::Dap(response.into())
98 }
99}
100
101impl From<Event> for crate::Message {
102 fn from(notification: Event) -> crate::Message {
103 crate::Message::Dap(notification.into())
104 }
105}
106
107impl From<Response> for LspOrDapResponse {
108 fn from(resp: Response) -> Self {
109 Self::Dap(resp)
110 }
111}
112
113impl TryFrom<LspOrDapResponse> for Response {
114 type Error = anyhow::Error;
115
116 fn try_from(resp: LspOrDapResponse) -> anyhow::Result<Self> {
117 match resp {
118 #[cfg(feature = "lsp")]
119 LspOrDapResponse::Lsp(_) => anyhow::bail!("unexpected LSP response"),
120 LspOrDapResponse::Dap(resp) => Ok(resp),
121 }
122 }
123}