use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ChunkHash(pub [u8; 32]);
impl ChunkHash {
pub fn from_bytes(bytes: [u8; 32]) -> Self {
Self(bytes)
}
pub fn hash(data: &[u8]) -> Self {
let hash = blake3::hash(data);
Self(*hash.as_bytes())
}
pub fn to_hex(&self) -> String {
hex::encode(self.0)
}
pub fn from_hex(s: &str) -> Result<Self, hex::FromHexError> {
let bytes = hex::decode(s)?;
let arr: [u8; 32] = bytes.try_into().map_err(|_| hex::FromHexError::InvalidStringLength)?;
Ok(Self(arr))
}
}
impl fmt::Debug for ChunkHash {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ChunkHash({})", &self.to_hex()[..16])
}
}
impl fmt::Display for ChunkHash {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", &self.to_hex()[..16])
}
}
pub type ChunkId = ChunkHash;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChunkMetadata {
pub hash: ChunkHash,
pub size: u64,
pub original_size: u64,
pub compression: CompressionType,
pub encrypted: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum CompressionType {
None,
Zstd,
Lz4,
}
#[derive(Debug, Clone)]
pub struct Chunk {
pub metadata: ChunkMetadata,
pub data: bytes::Bytes,
}
impl Chunk {
pub fn new(data: bytes::Bytes, original_size: u64, compression: CompressionType) -> Self {
let hash = ChunkHash::hash(&data);
Self {
metadata: ChunkMetadata {
hash,
size: data.len() as u64,
original_size,
compression,
encrypted: false,
},
data,
}
}
pub fn hash(&self) -> &ChunkHash {
&self.metadata.hash
}
}