use crate::{
error::{ErrorKind, Result},
runtime::{AsyncLittleEndianRead, AsyncLittleEndianWrite, AsyncStream},
};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub(crate) enum OpCode {
Reply = 1,
Query = 2004,
Message = 2013,
}
impl OpCode {
fn from_i32(i: i32) -> Result<Self> {
match i {
1 => Ok(OpCode::Reply),
2004 => Ok(OpCode::Query),
2013 => Ok(OpCode::Message),
other => Err(ErrorKind::OperationError {
message: format!("Invalid wire protocol opcode: {}", other),
}
.into()),
}
}
}
#[derive(Debug)]
pub(crate) struct Header {
pub length: i32,
pub request_id: i32,
pub response_to: i32,
pub op_code: OpCode,
}
impl Header {
pub(crate) const LENGTH: usize = 4 * std::mem::size_of::<i32>();
pub(crate) async fn write_to(&self, stream: &mut AsyncStream) -> Result<()> {
stream.write_i32(self.length).await?;
stream.write_i32(self.request_id).await?;
stream.write_i32(self.response_to).await?;
stream.write_i32(self.op_code as i32).await?;
Ok(())
}
pub(crate) async fn read_from(stream: &mut AsyncStream) -> Result<Self> {
let length = stream.read_i32().await?;
let request_id = stream.read_i32().await?;
let response_to = stream.read_i32().await?;
let op_code = OpCode::from_i32(stream.read_i32().await?)?;
Ok(Self {
length,
request_id,
response_to,
op_code,
})
}
}