1pub use crate::proto::{LspCodec, LspDecoder, LspEncoder};
2
3pub mod proto;
4
5#[derive(Debug)]
6pub enum Error {
7 Io(std::io::Error),
8 Serde(serde_json::Error),
9 Header(crate::proto::HeaderError),
10}
11
12impl From<std::io::Error> for Error {
13 fn from(io: std::io::Error) -> Error {
14 Error::Io(io)
15 }
16}
17
18impl From<serde_json::Error> for Error {
19 fn from(serde: serde_json::Error) -> Error {
20 Error::Serde(serde)
21 }
22}
23
24impl From<crate::proto::HeaderError> for Error {
25 fn from(header: crate::proto::HeaderError) -> Error {
26 Error::Header(header)
27 }
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33 use serde_json::json;
34 use tokio::runtime::Runtime;
35 use tokio_stream::StreamExt;
36 use tokio_util::codec::{FramedRead, FramedWrite};
37
38 #[test]
39 fn decode() {
40 let runtime = Runtime::new().unwrap();
41
42 let buf: &[u8] = include_bytes!(concat!(
43 env!("CARGO_MANIFEST_DIR"),
44 "/tests/fixtures/case1.jsonrpc"
45 ));
46
47 let reader = FramedRead::new(buf, LspDecoder::default());
48
49 let received = runtime
50 .block_on(reader.collect::<Result<Vec<_>, _>>())
51 .unwrap();
52 assert_eq!(
53 received,
54 vec![
55 json!({"jsonrpc": "2.0", "id": 1, "method": "textDocument/didOpen", "params": {}}),
56 json!({"jsonrpc": "2.0", "id": 2, "method": "textDocument/didOpen", "params": {}}),
57 ]
58 );
59 }
60
61 #[test]
62 fn encode() {
63 use futures::sink::SinkExt;
64
65 let mut writer = FramedWrite::new(vec![], LspEncoder);
66
67 let obj = json!({
68 "key": "value"
69 });
70
71 let rt = Runtime::new().unwrap();
72 let fut = SinkExt::send(&mut writer, obj);
73
74 let _ = rt.block_on(fut);
75
76 let buf = writer.into_inner();
77 let s = String::from_utf8(buf).unwrap();
78
79 assert_eq!(s, "Content-Length: 15\r\n\r\n{\"key\":\"value\"}");
80 }
81}