1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::io::{self, BufRead, Read, Write};
4
5#[derive(Debug, Deserialize)]
7pub struct JsonRpcRequest {
8 #[serde(default)]
9 pub jsonrpc: Option<String>,
10 #[serde(default)]
11 pub id: Option<Value>,
12 pub method: String,
13 #[serde(default)]
14 pub params: Option<Value>,
15}
16
17#[derive(Debug, Serialize, Deserialize)]
19pub struct JsonRpcResponse {
20 pub jsonrpc: String,
21 pub id: Option<Value>,
22 pub result: Option<Value>,
24 #[serde(skip_serializing_if = "Option::is_none")]
25 pub error: Option<JsonRpcError>,
26}
27
28#[derive(Debug, Serialize, Deserialize)]
30pub struct JsonRpcError {
31 pub code: i32,
32 pub message: String,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub data: Option<Value>,
35}
36
37pub fn read_next_message<R: BufRead + Read>(reader: &mut R) -> io::Result<Option<(String, bool)>> {
41 loop {
42 let mut line = String::new();
43 let n = reader.read_line(&mut line)?;
44 if n == 0 {
45 return Ok(None);
47 }
48
49 let trimmed = line.trim();
50 if trimmed.is_empty() {
51 continue;
52 }
53
54 if trimmed.starts_with('{') {
56 return Ok(Some((trimmed.to_string(), false)));
57 }
58
59 let low = trimmed.to_ascii_lowercase();
61 if low.starts_with("content-length:") {
62 let parts: Vec<&str> = trimmed.splitn(2, ':').collect();
64 let len: usize = parts
65 .get(1)
66 .map(|s| s.trim().parse().ok().unwrap_or(0))
67 .unwrap_or(0);
68
69 loop {
71 let mut hline = String::new();
72 let hn = reader.read_line(&mut hline)?;
73 if hn == 0 || hline.trim().is_empty() {
74 break;
75 }
76 }
77
78 if len == 0 {
80 continue;
81 }
82 let mut buf = vec![0u8; len];
83 reader.read_exact(&mut buf)?;
84 return Ok(Some((String::from_utf8_lossy(&buf).to_string(), true)));
85 }
86
87 continue;
89 }
90}
91
92pub fn write_response_with_length<W: Write>(writer: &mut W, body: &str) -> io::Result<()> {
94 let bytes = body.as_bytes();
95 let header = format!("Content-Length: {}\r\n\r\n", bytes.len());
96 writer.write_all(header.as_bytes())?;
97 writer.write_all(bytes)?;
98 writer.flush()?;
99 Ok(())
100}