lsp_io/
blocking.rs

1use lsp_ty::{NotificationMessage, OneOf3, RequestMessage, ResponseMessage};
2use std::io::{Read, Write};
3
4type IOResult<T> = std::io::Result<T>;
5
6use crate::utils::CodecState;
7
8/// protocol message reader/writer
9pub struct MessageCodec<S: Read + Write> {
10    stream: S,
11    state: CodecState,
12}
13
14impl<S: Read + Write> MessageCodec<S> {
15    pub fn new(stream: S) -> Self {
16        Self {
17            stream,
18            state: CodecState::default(),
19        }
20    }
21
22    /// get mutable ref of underlying stream
23    pub fn stream_mut(&mut self) -> &mut S {
24        &mut self.stream
25    }
26
27    fn poll(&mut self) -> IOResult<usize> {
28        let state = &mut self.state;
29        let count = self.stream.read(&mut state.read_buf)?;
30        if count == 0 {
31            return Err(std::io::Error::new(
32                std::io::ErrorKind::ConnectionAborted,
33                "read eof",
34            ));
35        }
36        state.read_data.extend_from_slice(&state.read_buf[..count]);
37        Ok(count)
38    }
39
40    fn consume_body(
41        &mut self,
42    ) -> IOResult<OneOf3<RequestMessage, ResponseMessage, NotificationMessage>> {
43        self.state
44            .consume_body()
45            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
46    }
47
48    /// read message from peer
49    ///
50    /// for server, most of times coming messages are request or notification,
51    /// at some rare case, there maybe a response, see [applyEdit](https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#workspace_applyEdit)
52    pub fn receive(
53        &mut self,
54    ) -> IOResult<OneOf3<RequestMessage, ResponseMessage, NotificationMessage>> {
55        loop {
56            if let Some(may_ok) = self.state.try_parse_header() {
57                may_ok.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
58                break;
59            } else {
60                self.poll()?;
61            }
62        }
63
64        while !self.state.body_ready() {
65            self.poll()?;
66        }
67
68        self.consume_body()
69    }
70
71    /// write message to peer
72    pub fn send(
73        &mut self,
74        message: OneOf3<RequestMessage, ResponseMessage, NotificationMessage>,
75    ) -> IOResult<()> {
76        let json_str = serde_json::to_string(&message)
77            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
78        let data = json_str.as_bytes();
79        self.stream.write_all(
80            format!(
81                "Content-Length: {}\r\nContent-Type: {}\r\n\r\n",
82                data.len(),
83                self.state.content_type
84            )
85            .as_bytes(),
86        )?;
87        self.stream.write_all(data)?;
88        Ok(())
89    }
90
91    /// helper function to send request only
92    pub fn send_req(&mut self, message: RequestMessage) -> IOResult<()> {
93        self.send(OneOf3::This(message))
94    }
95
96    /// helper function to send response only
97    pub fn send_resp(&mut self, message: ResponseMessage) -> IOResult<()> {
98        self.send(OneOf3::Among(message))
99    }
100
101    /// helper function to send notification only
102    pub fn send_notice(&mut self, message: NotificationMessage) -> IOResult<()> {
103        self.send(OneOf3::Other(message))
104    }
105}