1use serde::{Deserialize, Serialize};
4use std::fmt;
5
6#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
8pub struct ChunkHash(pub [u8; 32]);
9
10impl ChunkHash {
11 pub fn from_bytes(bytes: [u8; 32]) -> Self {
13 Self(bytes)
14 }
15
16 pub fn hash(data: &[u8]) -> Self {
18 let hash = blake3::hash(data);
19 Self(*hash.as_bytes())
20 }
21
22 pub fn to_hex(&self) -> String {
24 hex::encode(self.0)
25 }
26
27 pub fn from_hex(s: &str) -> Result<Self, hex::FromHexError> {
29 let bytes = hex::decode(s)?;
30 let arr: [u8; 32] = bytes.try_into().map_err(|_| hex::FromHexError::InvalidStringLength)?;
31 Ok(Self(arr))
32 }
33}
34
35impl fmt::Debug for ChunkHash {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 write!(f, "ChunkHash({})", &self.to_hex()[..16])
38 }
39}
40
41impl fmt::Display for ChunkHash {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 write!(f, "{}", &self.to_hex()[..16])
44 }
45}
46
47pub type ChunkId = ChunkHash;
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct ChunkMetadata {
53 pub hash: ChunkHash,
55 pub size: u64,
57 pub original_size: u64,
59 pub compression: CompressionType,
61 pub encrypted: bool,
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
67pub enum CompressionType {
68 None,
69 Zstd,
70 Lz4,
71}
72
73#[derive(Debug, Clone)]
75pub struct Chunk {
76 pub metadata: ChunkMetadata,
78 pub data: bytes::Bytes,
80}
81
82impl Chunk {
83 pub fn new(data: bytes::Bytes, original_size: u64, compression: CompressionType) -> Self {
85 let hash = ChunkHash::hash(&data);
86 Self {
87 metadata: ChunkMetadata {
88 hash,
89 size: data.len() as u64,
90 original_size,
91 compression,
92 encrypted: false,
93 },
94 data,
95 }
96 }
97
98 pub fn hash(&self) -> &ChunkHash {
100 &self.metadata.hash
101 }
102}