use std::io::Write;
use std::sync::{Arc, Mutex};
use serde_json::Value;
use tokio::io::{AsyncBufReadExt, BufReader};
use crate::error::{Result, SlopError};
use crate::server::{Connection, SlopServer};
struct StdioConnection {
stdout: Mutex<std::io::Stdout>,
}
impl Connection for StdioConnection {
fn send(&self, message: &Value) -> Result<()> {
let mut line = serde_json::to_string(message)?;
line.push('\n');
let mut stdout = self.stdout.lock().unwrap();
stdout
.write_all(line.as_bytes())
.map_err(|e| SlopError::Transport(e.to_string()))?;
stdout
.flush()
.map_err(|e| SlopError::Transport(e.to_string()))
}
fn close(&self) -> Result<()> {
Ok(())
}
}
pub async fn listen(slop: &SlopServer) -> Result<()> {
let conn: Arc<dyn Connection> = Arc::new(StdioConnection {
stdout: Mutex::new(std::io::stdout()),
});
slop.handle_connection(conn.clone());
let stdin = tokio::io::stdin();
let mut lines = BufReader::new(stdin).lines();
while let Ok(Some(line)) = lines.next_line().await {
let line = line.trim().to_string();
if line.is_empty() {
continue;
}
if let Ok(msg) = serde_json::from_str::<Value>(&line) {
slop.handle_message(&conn, &msg);
}
}
slop.handle_disconnect(&conn);
Ok(())
}