41 lines
1.2 KiB
Rust
41 lines
1.2 KiB
Rust
use crate::message::proto_message::ProtoMessage;
|
|
use crate::reader::errors::ProtoReadError;
|
|
use crate::reader::protoreader::ProtoReader;
|
|
use crate::reader::utils::AsyncPeek;
|
|
use async_trait::async_trait;
|
|
use tokio::io::{AsyncBufRead, AsyncReadExt};
|
|
|
|
#[async_trait]
|
|
pub trait OneWayProtoReader<T>
|
|
where
|
|
T: ProtoMessage,
|
|
{
|
|
async fn read_proto(&mut self) -> Result<T, ProtoReadError>;
|
|
}
|
|
|
|
#[async_trait]
|
|
impl<R, T> OneWayProtoReader<T> for ProtoReader<R>
|
|
where
|
|
R: AsyncBufRead + AsyncPeek + Unpin + Send,
|
|
T: ProtoMessage,
|
|
{
|
|
async fn read_proto(&mut self) -> Result<T, ProtoReadError> {
|
|
let variant = self.inner.read_u8().await?;
|
|
let length = self.inner.read_i32().await?;
|
|
|
|
if length < 4 {
|
|
return Err(ProtoReadError::InvalidLength(length));
|
|
}
|
|
if length > self.msg_len_limit {
|
|
return Err(ProtoReadError::LengthOverflow {
|
|
limit: self.msg_len_limit as usize,
|
|
actual: length as usize,
|
|
});
|
|
}
|
|
|
|
let mut data = vec![0u8; (length - 4) as usize];
|
|
self.inner.read_exact(&mut data).await?;
|
|
|
|
Ok(T::deserialize(variant, &data)?)
|
|
}
|
|
}
|