use crate::SwarmAddress;
use crate::chunk::error;
use crate::error::Result;
use bytes::{BufMut, Bytes, BytesMut};
pub type ChunkAddress = SwarmAddress;
pub trait ChunkMetadata {
fn bytes(&self) -> Bytes;
}
pub trait ChunkHeader {
type Metadata: ChunkMetadata;
fn id(&self) -> u8;
fn version(&self) -> u8;
fn metadata(&self) -> &Self::Metadata;
fn bytes(&self) -> Bytes {
let mut buf = BytesMut::with_capacity(2);
buf.put_u8(self.id());
buf.put_u8(self.version());
buf.put_slice(self.metadata().bytes().as_ref());
buf.freeze()
}
}
pub trait Chunk: Send + Sync + 'static {
type Header: ChunkHeader;
fn address(&self) -> &ChunkAddress;
fn header(&self) -> &Self::Header;
fn data(&self) -> &Bytes;
fn size(&self) -> usize {
self.header().bytes().len() + self.data().len()
}
fn verify(&self, expected: &ChunkAddress) -> Result<()> {
let actual = self.address();
if actual != expected {
return Err(error::ChunkError::verification_failed(*expected, *actual).into());
}
Ok(())
}
}
pub trait ChunkSerialization {
fn serialize_with_prefix(&self) -> Bytes;
}
impl<T: Chunk> ChunkSerialization for T {
fn serialize_with_prefix(&self) -> Bytes {
let mut bytes = BytesMut::with_capacity(2 + self.size());
bytes.extend(self.header().bytes());
bytes.extend(self.data());
bytes.freeze()
}
}
pub trait BmtChunk: Chunk {
fn span(&self) -> u64;
}