bsp_server/
message.rs

1use crate::Notification;
2use crate::Request;
3use crate::Response;
4use serde::{Deserialize, Serialize};
5use std::io;
6
7#[derive(Serialize, Deserialize, Debug, Clone)]
8#[serde(untagged)]
9pub enum Message {
10    Request(Request),
11    Response(Response),
12    Notification(Notification),
13}
14
15#[derive(Serialize)]
16struct JsonRpc {
17    jsonrpc: &'static str,
18    #[serde(flatten)]
19    msg: Message,
20}
21
22impl From<Message> for JsonRpc {
23    fn from(msg: Message) -> Self {
24        Self {
25            jsonrpc: "2.0",
26            msg,
27        }
28    }
29}
30
31impl Message {
32    pub(crate) fn read(r: &mut dyn io::BufRead) -> io::Result<Option<Message>> {
33        let text = match read_msg_text(r)? {
34            Some(text) => text,
35            None => return Ok(None),
36        };
37        let msg = serde_json::from_str(&text)?;
38        tracing::trace!("Got <<<<<<<<<<<<<<<<<<<<<<<<<\n\n{:#?}\n", msg);
39        Ok(Some(msg))
40    }
41
42    pub(crate) fn write(self, w: &mut dyn io::Write) -> io::Result<()> {
43        tracing::trace!("Sent >>>>>>>>>>>>>>>>>>>>>>>>>\n\n{:#?}\n", self);
44        let msg = serde_json::to_string(&JsonRpc::from(self))?;
45        write!(w, "Content-Length: {}\r\n\r\n", msg.len())?;
46        w.write_all(msg.as_bytes())?;
47        w.flush()?;
48        Ok(())
49    }
50}
51
52fn invalid_data(error: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> io::Error {
53    io::Error::new(io::ErrorKind::InvalidData, error)
54}
55
56macro_rules! invalid_data { ($($tt:tt)*) => (invalid_data(format!($($tt)*))) }
57
58fn read_msg_text(inp: &mut dyn io::BufRead) -> io::Result<Option<String>> {
59    let mut size = None;
60    let mut buf = String::new();
61
62    loop {
63        buf.clear();
64        if inp.read_line(&mut buf)? == 0 {
65            return Ok(None);
66        }
67        if !buf.ends_with("\r\n") {
68            return Err(invalid_data!("malformed header: {:?}", buf));
69        }
70        let buf = &buf[..buf.len() - 2];
71        if buf.is_empty() {
72            break;
73        }
74        let mut parts = buf.splitn(2, ": ");
75        let header_name = parts.next().unwrap();
76        let header_value = parts
77            .next()
78            .ok_or_else(|| invalid_data!("malformed header: {:?}", buf))?;
79        if header_name == "Content-Length" {
80            size = Some(header_value.parse::<usize>().map_err(invalid_data)?);
81        }
82    }
83
84    let size: usize = size.ok_or_else(|| invalid_data!("no Content-Length"))?;
85    let mut buf = buf.into_bytes();
86
87    buf.resize(size, 0);
88    inp.read_exact(&mut buf)?;
89
90    Ok(Some(String::from_utf8(buf).map_err(invalid_data)?))
91}