1use std::{
2 fmt::Debug,
3 io::{BufRead, BufReader, BufWriter, Read, Write},
4 sync::{Arc, Mutex},
5};
6
7use serde_json;
8
9use crate::{
10 base_message::{BaseMessage, Sendable},
11 errors::{DeserializationError, ServerError},
12 events::Event,
13 requests::Request,
14 responses::Response,
15 reverse_requests::ReverseRequest,
16};
17
18#[derive(Debug)]
19enum ServerState {
20 Header,
22 Content,
24}
25
26pub struct Server<R: Read, W: Write> {
31 input_buffer: BufReader<R>,
32
33 pub output: Arc<Mutex<ServerOutput<W>>>,
36}
37
38pub struct ServerOutput<W: Write> {
45 output_buffer: BufWriter<W>,
46 sequence_number: i64,
47}
48
49impl<R: Read, W: Write> Server<R, W> {
50 pub fn new(input: BufReader<R>, output: BufWriter<W>) -> Self {
52 let server_output = Arc::new(Mutex::new(ServerOutput {
53 output_buffer: output,
54 sequence_number: 0,
55 }));
56
57 Self {
58 input_buffer: input,
59 output: server_output,
60 }
61 }
62
63 pub fn poll_request(&mut self) -> Result<Option<Request>, ServerError> {
68 let mut state = ServerState::Header;
69 let mut buffer = String::new();
70 let mut content_length: usize = 0;
71
72 loop {
73 match self.input_buffer.read_line(&mut buffer) {
74 Ok(read_size) => {
75 if read_size == 0 {
76 break Ok(None);
77 }
78 match state {
79 ServerState::Header => {
80 let parts: Vec<&str> = buffer.trim_end().split(':').collect();
81 if parts.len() == 2 {
82 match parts[0] {
83 "Content-Length" => {
84 content_length = match parts[1].trim().parse() {
85 Ok(val) => val,
86 Err(_) => {
87 return Err(ServerError::HeaderParseError {
88 line: buffer,
89 });
90 }
91 };
92 buffer.clear();
93 buffer.reserve(content_length);
94 state = ServerState::Content;
95 }
96 other => {
97 return Err(ServerError::UnknownHeader {
98 header: other.to_string(),
99 });
100 }
101 }
102 } else {
103 return Err(ServerError::HeaderParseError { line: buffer });
104 }
105 }
106 ServerState::Content => {
107 buffer.clear();
108 let mut content = vec![0; content_length];
109 self.input_buffer
110 .read_exact(content.as_mut_slice())
111 .map_err(ServerError::IoError)?;
112
113 let content = std::str::from_utf8(content.as_slice()).map_err(|e| {
114 ServerError::ParseError(DeserializationError::DecodingError(e))
115 })?;
116 eprintln!(
117 "[DAP-RS] Received content ({content_length} bytes): {content}"
118 );
119 let raw: serde_json::Value =
123 serde_json::from_str(content).map_err(|e| {
124 eprintln!("[DAP-RS] JSON parse error: {e}");
125 ServerError::ParseError(DeserializationError::SerdeError(e))
126 })?;
127 let seq = raw.get("seq").and_then(|v| v.as_i64()).ok_or_else(|| {
128 eprintln!("[DAP-RS] Missing seq field");
129 ServerError::ParseError(DeserializationError::SerdeError(
130 serde_json::from_str::<()>("\"missing seq field\"")
131 .unwrap_err(),
132 ))
133 })?;
134 let command: crate::requests::Command = if raw
141 .get("arguments")
142 .and_then(|v| v.as_object())
143 .is_some_and(|m| m.is_empty())
144 {
145 let mut without_args = raw.clone();
146 without_args.as_object_mut().unwrap().remove("arguments");
147 match serde_json::from_value::<crate::requests::Command>(
148 without_args,
149 ) {
150 Ok(cmd) => cmd,
151 Err(_) => serde_json::from_value(raw.clone()).map_err(|e| {
152 eprintln!("[DAP-RS] Command deserialize error: {e}");
153 ServerError::ParseError(DeserializationError::SerdeError(e))
154 })?,
155 }
156 } else {
157 serde_json::from_value(raw.clone()).map_err(|e| {
158 eprintln!("[DAP-RS] Command deserialize error: {e}");
159 ServerError::ParseError(DeserializationError::SerdeError(e))
160 })?
161 };
162 eprintln!("[DAP-RS] Successfully parsed request seq={seq}");
163 let request = Request { seq, command };
164 return Ok(Some(request));
165 }
166 }
167 }
168 Err(e) => return Err(ServerError::IoError(e)),
169 }
170 }
171 }
172
173 pub fn send(&mut self, body: Sendable) -> Result<(), ServerError> {
174 let mut output = self.output.lock().map_err(|_| ServerError::OutputLockError)?;
175 output.send(body)
176 }
177
178 pub fn respond(&mut self, response: Response) -> Result<(), ServerError> {
179 self.send(Sendable::Response(response))
180 }
181
182 pub fn send_event(&mut self, event: Event) -> Result<(), ServerError> {
183 self.send(Sendable::Event(event))
184 }
185
186 pub fn send_reverse_request(&mut self, request: ReverseRequest) -> Result<(), ServerError> {
187 self.send(Sendable::ReverseRequest(request))
188 }
189}
190
191impl<W: Write> ServerOutput<W> {
192 pub fn send(&mut self, body: Sendable) -> Result<(), ServerError> {
193 self.sequence_number += 1;
194
195 let message = BaseMessage {
196 seq: self.sequence_number,
197 message: body,
198 };
199
200 let resp_json = serde_json::to_string(&message).map_err(ServerError::SerializationError)?;
201 write!(self.output_buffer, "Content-Length: {}\r\n\r\n", resp_json.len())
202 .map_err(ServerError::IoError)?;
203
204 write!(self.output_buffer, "{}\r\n", resp_json).map_err(ServerError::IoError)?;
205 self.output_buffer.flush().map_err(ServerError::IoError)?;
206 Ok(())
207 }
208
209 pub fn respond(&mut self, response: Response) -> Result<(), ServerError> {
210 self.send(Sendable::Response(response))
211 }
212
213 pub fn send_event(&mut self, event: Event) -> Result<(), ServerError> {
214 self.send(Sendable::Event(event))
215 }
216
217 pub fn send_reverse_request(&mut self, request: ReverseRequest) -> Result<(), ServerError> {
218 self.send(Sendable::ReverseRequest(request))
219 }
220}
221
222#[cfg(test)]
223mod tests {
224
225 use std::io::Cursor;
226
227 use serde_json::Value;
228
229 use super::*;
230 use crate::requests::{AttachOrLaunchArguments, Command, RestartArguments};
231
232 fn simulate_poll_request(input: &str) -> Request {
233 let mut server_in = Cursor::new(input.as_bytes().to_vec());
234 let server_out = Vec::new();
235 let mut server = Server::new(BufReader::new(&mut server_in), BufWriter::new(server_out));
236
237 server.poll_request().unwrap().unwrap()
238 }
239
240 #[test]
241 fn test_server_init_request() {
242 let req = simulate_poll_request(
243 "Content-Length: 155\r\n\r\n{\"seq\": 152,\"type\": \"request\",\"command\": \
244 \"initialize\",\"arguments\": {\"adapterID\": \
245 \"0001e357-72c7-4f03-ae8f-c5b54bd8dabf\", \"clientName\": \"Some Cool Editor\"}}",
246 );
247
248 assert_eq!(req.seq, 152);
249 assert!(matches!(req.command, Command::Initialize { .. }));
250 }
251
252 #[test]
253 fn test_server_restart_request() {
254 let req = simulate_poll_request(
255 "Content-Length: 67\r\n\r\n{\"seq\": 152,\"type\": \"request\",\"command\": \
256 \"restart\",\"arguments\": {}}",
257 );
258
259 assert!(matches!(
260 req.command,
261 Command::Restart {
262 0: RestartArguments { arguments: None }
263 }
264 ));
265
266 let req = simulate_poll_request(
268 "Content-Length: 96\r\n\r\n{\"seq\": 152,\"type\": \"request\",\"command\": \
269 \"restart\",\"arguments\": {\"arguments\": {\"noDebug\":true}}}",
270 );
271 assert!(matches!(
272 req.command,
273 Command::Restart {
274 0: RestartArguments {
275 arguments: Some(AttachOrLaunchArguments {
276 no_debug: Some(_),
277 ..
278 })
279 }
280 }
281 ));
282
283 let req = simulate_poll_request(
285 "Content-Length: 98\r\n\r\n{\"seq\": 152,\"type\": \"request\",\"command\": \
286 \"restart\",\"arguments\": {\"arguments\": {\"__restart\":true}}}",
287 );
288 assert!(matches!(
289 req.command,
290 Command::Restart {
291 0: RestartArguments {
292 arguments: Some(AttachOrLaunchArguments {
293 restart_data: Some(Value::Bool(true)),
294 ..
295 })
296 }
297 }
298 ));
299 }
300}