mod range;
pub mod mem_io_handle;
mod macros;
mod world;
#[cfg(test)]
mod tests;
use std::ops::Deref;
use async_trait::async_trait;
use futures_lite::AsyncRead;
pub use world::{iter::Iter, iter::Lazy, Chunk, Chunks, Dim, Select, World};
#[doc(hidden)]
pub use futures_lite::StreamExt;
pub trait Data: Sized + Send + Sync + Unpin {
const DIMS: usize;
const VERSION: u32;
fn dim(&self, dim: usize) -> u64;
fn decode<B: bytes::Buf>(version: u32, dims: &[u64], buf: B) -> std::io::Result<Self>;
fn encode<B: bytes::BufMut>(&self, buf: B) -> std::io::Result<()>;
}
const ARRAY_VERSION: u32 = 0;
impl<const DIMS: usize> Data for [u64; DIMS] {
const DIMS: usize = DIMS;
const VERSION: u32 = ARRAY_VERSION;
#[inline]
fn dim(&self, dim: usize) -> u64 {
self[dim]
}
#[inline]
fn decode<B: bytes::Buf>(_version: u32, dims: &[u64], _buf: B) -> std::io::Result<Self> {
let mut this = [0; DIMS];
this.copy_from_slice(dims);
Ok(this)
}
#[inline]
fn encode<B: bytes::BufMut>(&self, _buf: B) -> std::io::Result<()> {
Ok(())
}
}
#[async_trait]
pub trait IoHandle: Send + Sync {
type Read<'a>: AsyncRead + Unpin + Send + Sync + 'a
where
Self: 'a;
#[inline]
fn hint_is_valid(&self, pos: &[usize]) -> bool {
let _ = pos;
true
}
async fn read_chunk<const DIMS: usize>(
&self,
pos: [usize; DIMS],
) -> std::io::Result<(u32, Self::Read<'_>)>;
}
impl<P, T> IoHandle for P
where
T: IoHandle + 'static,
P: Deref<Target = T> + Send + Sync,
{
type Read<'a> = T::Read<'a> where Self: 'a;
#[inline]
fn hint_is_valid(&self, pos: &[usize]) -> bool {
self.deref().hint_is_valid(pos)
}
#[doc = " Gets reader for given chunk position."]
#[must_use]
#[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
#[inline]
fn read_chunk<'life0, 'async_trait, const DIMS: usize>(
&'life0 self,
pos: [usize; DIMS],
) -> ::core::pin::Pin<
Box<
dyn ::core::future::Future<Output = std::io::Result<(u32, Self::Read<'_>)>>
+ ::core::marker::Send
+ 'async_trait,
>,
>
where
'life0: 'async_trait,
Self: 'async_trait,
{
self.deref().read_chunk(pos)
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("io err: {0}")]
Io(std::io::Error),
#[error("requesting value not found")]
ValueNotFound,
#[error("requesting value was moved to another chunk buffer")]
ValueMoved,
#[error("value {value} out of range [{}, {}]", range.0, range.1)]
ValueOutOfRange { range: (u64, u64), value: u64 },
}
type Result<T> = std::result::Result<T, Error>;