use crate::decoder::XzError;
use sha2::{Digest, Sha256};
#[derive(Clone, Default, Debug)]
#[repr(transparent)]
pub struct XzSha256 {
delegate: Option<Sha256>,
}
impl XzSha256 {
pub(crate) const fn new() -> Self {
Self { delegate: None }
}
fn delegate(&mut self) -> &mut Sha256 {
if let Some(ref mut delegate) = self.delegate {
return delegate;
}
self.delegate = Some(Sha256::new());
self.delegate.as_mut().expect("cannot fail")
}
fn take_delegate(&mut self) -> Sha256 {
self.delegate.take().unwrap_or_default()
}
pub const fn reset(&mut self) {
self.delegate = None;
}
pub fn update(&mut self, buf: &[u8]) {
Digest::update(self.delegate(), buf);
}
pub fn validate(&mut self, buf: &[u8]) -> Result<(), XzError> {
let state = self.take_delegate();
let binding = state.finalize();
let actual = binding.as_slice();
if buf != actual {
let actual: [u8; 32] = actual.try_into().map_err(|_| XzError::CorruptedData)?; let expected: [u8; 32] = buf.try_into().map_err(|_| XzError::CorruptedData)?; return Err(XzError::ContentSha256Mismatch(actual, expected));
}
Ok(())
}
}