use crate::imp::core::Bytes32;
use alloc::vec::Vec;
use sha2::{Digest, Sha256};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Chunk {
pub hash: Bytes32,
pub data: Vec<u8>,
pub offset: usize,
}
impl Chunk {
pub fn new(offset: usize, data: Vec<u8>) -> Self {
let hash = hash_data(&data);
Chunk { hash, data, offset }
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
}
pub fn hash_data(data: &[u8]) -> Bytes32 {
let mut hasher = Sha256::new();
hasher.update(data);
let digest = hasher.finalize();
let mut out = [0u8; 32];
out.copy_from_slice(&digest);
Bytes32(out)
}
#[cfg(all(test, not(target_arch = "wasm32")))]
mod tests {
use super::*;
#[test]
fn chunk_hashes_empty_data() {
let c = Chunk::new(0, Vec::new());
assert_eq!(
c.hash.to_hex(),
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
);
assert_eq!(c.offset, 0);
assert!(c.data.is_empty());
}
#[test]
fn chunk_hashes_abc() {
let c = Chunk::new(7, b"abc".to_vec());
assert_eq!(
c.hash.to_hex(),
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
);
assert_eq!(c.offset, 7);
assert_eq!(c.data, b"abc");
}
#[test]
fn chunk_len_reports_data_length() {
let c = Chunk::new(0, vec![1, 2, 3, 4]);
assert_eq!(c.len(), 4);
assert!(!c.is_empty());
}
#[test]
fn hash_data_matches_chunk_hash() {
let data = vec![9u8, 8, 7, 6, 5];
let c = Chunk::new(0, data.clone());
assert_eq!(c.hash, hash_data(&data));
}
}