use crate::ipc_types::Init as InitBlob;
use serde::de::Error as SerdeError;
use thiserror::Error;
use tokio::io::{self};
#[derive(Debug, Error)]
pub enum InitError {
#[error("stdin closed unexpectedly during handshake")]
StdinClosed,
#[error("stdin read error: {0}")]
Io(#[from] io::Error),
#[error("failed to parse Init JSON: {0}")]
Json(#[from] serde_json::Error),
}
pub async fn read_init() -> Result<InitBlob, InitError> {
use tokio::io::AsyncReadExt;
let mut stdin = io::stdin();
let mut buf = Vec::with_capacity(1024);
let mut byte = [0u8; 1];
loop {
let n = stdin.read(&mut byte).await?;
if n == 0 {
return Err(InitError::StdinClosed);
}
if byte[0] == b'\n' {
break; }
buf.push(byte[0]);
if buf.len() > 1_048_576 {
return Err(InitError::Json(serde_json::Error::custom(
"Init line exceeded 1 MiB – possible protocol corruption",
)));
}
}
let line = String::from_utf8(buf)
.map_err(|e| InitError::Json(serde_json::Error::custom(e.to_string())))?;
let init: InitBlob = serde_json::from_str(&line)?;
Ok(init)
}