use crate::partial::container::{PartialContainerType, PartialContainer};
use tokio::io::{AsyncRead, AsyncSeek};
use crate::partial::PartialReader;
use crate::error::{TychoResult, TychoError};
use async_trait::async_trait;
#[async_trait]
pub trait PartialContainerTypeAsync: PartialContainerType {
async fn read_item_async<R: AsyncRead + AsyncSeek + Unpin + Send>(reader: &mut PartialReader<R>, params: &Self::ItemParam) -> TychoResult<Self::ItemType>;
}
impl<T: PartialContainerTypeAsync> PartialContainer<T> {
pub(crate) async fn next_item_async<R: AsyncRead + AsyncSeek + Unpin + Send>(&mut self, reader: &mut PartialReader<R>) -> TychoResult<Option<T::ItemType>> {
#[cfg(feature="partial_state")]
if self.pointer.ident != reader.ident {
return Err(TychoError::OutdatedPointer)
}
if self.head == self.pointer.size {
return Ok(None);
}
let top = reader.pointer.clone();
reader.jump_async(&(self.pointer.pos + self.head)).await?;
let head_start = reader.pointer;
let item = T::read_item_async(reader, &self.param).await?;
self.head += reader.pointer - head_start;
reader.jump_async(&top).await?;
Ok(Some(item))
}
pub async fn next_async<R: AsyncRead + AsyncSeek + Unpin + Send>(&mut self, reader: &mut PartialReader<R>) -> TychoResult<Option<T::ItemType>> {
self.next_item_async(reader).await
}
pub async fn collect_async<R: AsyncRead + AsyncSeek + Unpin + Send>(&mut self, reader: &mut PartialReader<R>) -> TychoResult<Vec<T::ItemType>> {
let mut items = Vec::new();
while let Some(item) = self.next_item_async(reader).await? {
items.push(item);
}
Ok(items)
}
}