pub mod field;
pub mod packet;
use field::Field;
use crate::common::BOUNDARY_MARKER;
#[derive(Debug)]
pub struct Chunks<F: Field> {
inner: Vec<Chunk<F>>,
chunk_size: usize,
}
#[derive(Debug, thiserror::Error)]
pub enum ChunksError {
#[error("data is empty")]
EmptyData,
#[error("chunk count is zero")]
ZeroChunkCount,
#[error("chunk size is zero")]
ZeroChunkSize,
}
impl<F: Field> Chunks<F> {
pub fn new(data: &[u8], chunk_count: usize) -> Result<Self, ChunksError> {
if data.is_empty() {
return Err(ChunksError::EmptyData);
}
if chunk_count == 0 {
return Err(ChunksError::ZeroChunkCount);
}
let mut data = Vec::from(data.as_ref());
data.push(BOUNDARY_MARKER);
let chunk_size = data.len().div_ceil(chunk_count);
let chunk_size = chunk_size.div_ceil(F::SAFE_CAPACITY) * F::SAFE_CAPACITY;
let padded_len = chunk_size * chunk_count;
data.resize(padded_len, 0);
let chunks = data.chunks_exact(chunk_size).map(Chunk::from_bytes).collect();
Ok(Self { inner: chunks, chunk_size })
}
pub fn chunk_size(&self) -> usize {
self.chunk_size
}
pub fn inner(&self) -> &[Chunk<F>] {
&self.inner
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
}
#[derive(Debug, Clone)]
pub struct Chunk<F: Field> {
symbols: Vec<F>,
#[allow(unused)]
size: usize,
}
impl<F: Field> Chunk<F> {
pub(crate) fn from_bytes(bytes: &[u8]) -> Self {
let size = bytes.len();
Self { symbols: bytes.chunks(F::SAFE_CAPACITY).map(|c| F::from_bytes(c)).collect(), size }
}
pub(crate) fn symbols(&self) -> &[F] {
&self.symbols
}
}