use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::io::{self, BufRead, Read, Write};
#[derive(Debug, Deserialize)]
pub struct JsonRpcRequest {
#[serde(default)]
pub jsonrpc: Option<String>,
#[serde(default)]
pub id: Option<Value>,
pub method: String,
#[serde(default)]
pub params: Option<Value>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct JsonRpcResponse {
pub jsonrpc: String,
pub id: Option<Value>,
pub result: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<JsonRpcError>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct JsonRpcError {
pub code: i32,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Value>,
}
pub fn read_next_message<R: BufRead + Read>(reader: &mut R) -> io::Result<Option<(String, bool)>> {
loop {
let mut line = String::new();
let n = reader.read_line(&mut line)?;
if n == 0 {
return Ok(None);
}
let trimmed = line.trim();
if trimmed.is_empty() {
continue;
}
if trimmed.starts_with('{') {
return Ok(Some((trimmed.to_string(), false)));
}
let low = trimmed.to_ascii_lowercase();
if low.starts_with("content-length:") {
let parts: Vec<&str> = trimmed.splitn(2, ':').collect();
let len: usize = parts
.get(1)
.map(|s| s.trim().parse().ok().unwrap_or(0))
.unwrap_or(0);
loop {
let mut hline = String::new();
let hn = reader.read_line(&mut hline)?;
if hn == 0 || hline.trim().is_empty() {
break;
}
}
if len == 0 {
continue;
}
let mut buf = vec![0u8; len];
reader.read_exact(&mut buf)?;
return Ok(Some((String::from_utf8_lossy(&buf).to_string(), true)));
}
continue;
}
}
pub fn write_response_with_length<W: Write>(writer: &mut W, body: &str) -> io::Result<()> {
let bytes = body.as_bytes();
let header = format!("Content-Length: {}\r\n\r\n", bytes.len());
writer.write_all(header.as_bytes())?;
writer.write_all(bytes)?;
writer.flush()?;
Ok(())
}