use std::io::{Read, Write};
use serde::{Deserialize, Serialize, de::DeserializeOwned};
use thiserror::Error;
pub const DEFAULT_MAX_FRAME_BYTES: usize = 8 * 1024 * 1024;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum CompressorRequest {
Health,
CompressionDistance {
left: Vec<u8>,
right: Vec<u8>,
},
CompressionDistanceChain {
left_parts: Vec<Vec<u8>>,
right_parts: Vec<Vec<u8>>,
},
IntrinsicDependence {
data: Vec<u8>,
max_order: i64,
},
BatchCompressionDistance {
target: Vec<u8>,
candidates: Vec<Vec<u8>>,
},
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum CompressorResponse {
Health { ok: bool },
CompressionDistance { value: f64 },
IntrinsicDependence { value: f64 },
BatchCompressionDistance { values: Vec<f64> },
Error { message: String },
}
#[derive(Debug, Error)]
pub enum IpcError {
#[error("i/o error: {0}")]
Io(#[from] std::io::Error),
#[error("serde error: {0}")]
Serde(#[from] serde_json::Error),
#[error("frame exceeds max length")]
FrameTooLarge,
}
pub fn write_frame<T: Serialize>(writer: &mut impl Write, value: &T) -> Result<(), IpcError> {
let payload = serde_json::to_vec(value)?;
let len = u32::try_from(payload.len()).map_err(|_| IpcError::FrameTooLarge)?;
writer.write_all(&len.to_be_bytes())?;
writer.write_all(&payload)?;
writer.flush()?;
Ok(())
}
pub fn read_frame<T: DeserializeOwned>(
reader: &mut impl Read,
max_bytes: usize,
) -> Result<T, IpcError> {
let mut len_buf = [0_u8; 4];
reader.read_exact(&mut len_buf)?;
let len = u32::from_be_bytes(len_buf) as usize;
if len > max_bytes {
return Err(IpcError::FrameTooLarge);
}
let mut payload = vec![0_u8; len];
reader.read_exact(&mut payload)?;
Ok(serde_json::from_slice(&payload)?)
}