use crate::error_codes::PARSE as E_PARSE;
use crate::server::{err, Request, Response, Server};
use serde_json::Value;
use std::sync::Arc;
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter};
pub async fn stdio_loop(server: Arc<Server>) -> std::io::Result<()> {
let mut stdin = BufReader::new(tokio::io::stdin()).lines();
let mut stdout = BufWriter::new(tokio::io::stdout());
while let Some(line) = stdin.next_line().await? {
if line.trim().is_empty() {
continue;
}
match serde_json::from_str::<Request>(&line) {
Ok(req) => {
if let Some(resp) = server.handle(req).await {
write_response(&mut stdout, &resp).await?;
}
}
Err(e) => {
let resp = err(Value::Null, E_PARSE, format!("parse error: {}", e));
write_response(&mut stdout, &resp).await?;
}
}
}
Ok(())
}
async fn write_response<W>(out: &mut W, resp: &Response) -> std::io::Result<()>
where
W: AsyncWriteExt + Unpin,
{
let line = serde_json::to_string(resp).map_err(std::io::Error::other)?;
out.write_all(line.as_bytes()).await?;
out.write_all(b"\n").await?;
out.flush().await
}