mylang_lsp_server/
receiver.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use actix::{Actor, Addr, Context, ContextFutureSpawner, WrapFuture};
use log::{info, warn};
use regex::Regex;
use tokio::io::{self, AsyncBufReadExt, AsyncReadExt, BufReader};

use crate::{message::LspMessage, responder::Responder};

/// 言語クライアントからのメッセージを受け取るアクター
pub struct Receiver {
    responder: Addr<Responder>,
}

impl Receiver {
    pub fn new(responder: Addr<Responder>) -> Self {
        Self { responder }
    }
}

impl Actor for Receiver {
    type Context = Context<Self>;

    fn started(&mut self, ctx: &mut Self::Context) {
        let responder = self.responder.clone();

        async move {
            let stdin = BufReader::new(io::stdin());
            let mut lines = stdin.lines();
            let re = Regex::new(r"Content-Length: (\d+)").unwrap();

            while let Ok(Some(line)) = lines.next_line().await {
                if let Some(caps) = re.captures(&line) {
                    let len = 2 + caps[1].parse::<usize>().unwrap();

                    let mut msg_buf = vec![0u8; len];
                    let reader = lines.get_mut();
                    reader.read_exact(&mut msg_buf).await.unwrap();
                    reader.consume(len);

                    let msg = String::from_utf8(msg_buf).unwrap();
                    let msg: LspMessage = serde_json::from_str(&msg).unwrap();
                    info!("<-- {:?}", msg);

                    responder.send(msg).await.unwrap();
                } else {
                    warn!("Skiped: {}", line);
                }
            }
        }
        .into_actor(self)
        .wait(ctx);
    }
}