use mountpoint_s3_client::checksums::{crc32, crc32c, crc64nvme, sha1, sha256};
use mountpoint_s3_client::config::Allocator;
use mountpoint_s3_client::types::{ChecksumAlgorithm, UploadChecksum};
use thiserror::Error;
#[derive(Debug, Default)]
pub enum ChecksumHasher {
#[default]
None,
Crc64nvme(crc64nvme::Crc64nvmeHasher),
Crc32(crc32::Hasher),
Crc32c(crc32c::Hasher),
Sha1(sha1::Sha1Hasher),
Sha256(sha256::Sha256Hasher),
}
impl ChecksumHasher {
pub fn new(checksum_algorithm: &Option<ChecksumAlgorithm>) -> Result<Self, ChecksumHasherError> {
match checksum_algorithm {
Some(ChecksumAlgorithm::Crc64nvme) => Ok(Self::Crc64nvme(crc64nvme::Crc64nvmeHasher::new())),
Some(ChecksumAlgorithm::Crc32) => Ok(Self::Crc32(crc32::Hasher::new())),
Some(ChecksumAlgorithm::Crc32c) => Ok(Self::Crc32c(crc32c::Hasher::new())),
Some(ChecksumAlgorithm::Sha1) => Ok(Self::Sha1(sha1::Sha1Hasher::new(&Allocator::default())?)),
Some(ChecksumAlgorithm::Sha256) => Ok(Self::Sha256(sha256::Sha256Hasher::new(&Allocator::default())?)),
Some(other) => Err(ChecksumHasherError::UnsupportedChecksumAlgorithm(other.clone())),
None => Ok(Self::None),
}
}
pub fn update(&mut self, data: &[u8]) -> Result<(), ChecksumHasherError> {
match self {
ChecksumHasher::None => {}
ChecksumHasher::Crc64nvme(hasher) => hasher.update(data),
ChecksumHasher::Crc32(hasher) => hasher.update(data),
ChecksumHasher::Crc32c(hasher) => hasher.update(data),
ChecksumHasher::Sha1(hasher) => hasher.update(data)?,
ChecksumHasher::Sha256(hasher) => hasher.update(data)?,
};
Ok(())
}
pub fn finalize(self) -> Result<Option<UploadChecksum>, ChecksumHasherError> {
match self {
ChecksumHasher::None => Ok(None),
ChecksumHasher::Crc64nvme(hasher) => Ok(Some(UploadChecksum::Crc64nvme(hasher.finalize()))),
ChecksumHasher::Crc32(hasher) => Ok(Some(UploadChecksum::Crc32(hasher.finalize()))),
ChecksumHasher::Crc32c(hasher) => Ok(Some(UploadChecksum::Crc32c(hasher.finalize()))),
ChecksumHasher::Sha1(hasher) => Ok(Some(UploadChecksum::Sha1(hasher.finalize(&Allocator::default())?))),
ChecksumHasher::Sha256(hasher) => Ok(Some(UploadChecksum::Sha256(hasher.finalize(&Allocator::default())?))),
}
}
}
#[derive(Debug, Error)]
pub enum ChecksumHasherError {
#[error("Checksum algorithm not supported: {0}")]
UnsupportedChecksumAlgorithm(ChecksumAlgorithm),
#[error("Unknown CRT error")]
CrtError(#[from] mountpoint_s3_client::error::CrtError),
}