feat: create digest engine with Sha256/Md5/None and integrate with save mode

This commit is contained in:
Andrew Phillips (aider)
2025-05-12 18:21:34 -03:00
parent f6b6bc5768
commit 41060c3029
5 changed files with 130 additions and 0 deletions

37
src/digest_engine.rs Normal file
View File

@@ -0,0 +1,37 @@
use std::io;
use std::path::PathBuf;
use log::*;
use strum::IntoEnumIterator;
pub mod none;
pub mod sha2;
pub mod program;
use crate::digest_engine::none::DigestEngineNone;
use crate::digest_engine::sha2::DigestEngineSha256;
use crate::digest_engine::program::DigestEngineProgram;
#[derive(Debug, Eq, PartialEq, Clone, strum::EnumIter, strum::Display, strum::EnumString, Enum)]
#[strum(ascii_case_insensitive)]
pub enum DigestType {
Sha256,
Md5,
None,
}
pub trait DigestEngine {
fn create(&self) -> Box<dyn DigestEngine>;
fn update(&mut self, data: &[u8]) -> io::Result<()>;
fn finalize(&mut self) -> io::Result<String>;
}
pub fn get_engine(digest_type: DigestType) -> Box<dyn DigestEngine> {
match digest_type {
DigestType::Sha256 => Box::new(DigestEngineSha256::new()),
DigestType::Md5 => Box::new(DigestEngineProgram::new("md5sum")),
DigestType::None => Box::new(DigestEngineNone::new()),
}
}

25
src/digest_engine/none.rs Normal file
View File

@@ -0,0 +1,25 @@
use std::io;
use log::*;
#[derive(Debug, Eq, PartialEq, Clone, Default)]
pub struct DigestEngineNone {}
impl DigestEngineNone {
pub fn new() -> DigestEngineNone {
DigestEngineNone {}
}
}
impl DigestEngine for DigestEngineNone {
fn create(&self) -> Box<dyn DigestEngine> {
Box::new(Self::new())
}
fn update(&mut self, _data: &[u8]) -> io::Result<()> {
Ok(())
}
fn finalize(&mut self) -> io::Result<String> {
Ok("none".to_string())
}
}

View File

@@ -0,0 +1,28 @@
use std::io;
use std::process::{Command, Stdio};
use log::*;
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct DigestEngineProgram {
program: String,
}
impl DigestEngineProgram {
pub fn new(program: &str) -> DigestEngineProgram {
DigestEngineProgram { program: program.to_string() }
}
}
impl DigestEngine for DigestEngineProgram {
fn create(&self) -> Box<dyn DigestEngine> {
Box::new(Self::new(&self.program))
}
fn update(&mut self, _data: &[u8]) -> io::Result<()> {
Ok(())
}
fn finalize(&mut self) -> io::Result<String> {
Ok("program".to_string())
}
}

30
src/digest_engine/sha2.rs Normal file
View File

@@ -0,0 +1,30 @@
use std::io;
use log::*;
use sha2::{Digest, Sha256};
#[derive(Debug, Eq, PartialEq, Clone, Default)]
pub struct DigestEngineSha256 {
hasher: Sha256,
}
impl DigestEngineSha256 {
pub fn new() -> DigestEngineSha256 {
DigestEngineSha256 { hasher: Sha256::new() }
}
}
impl DigestEngine for DigestEngineSha256 {
fn create(&self) -> Box<dyn DigestEngine> {
Box::new(Self::new())
}
fn update(&mut self, data: &[u8]) -> io::Result<()> {
self.hasher.update(data);
Ok(())
}
fn finalize(&mut self) -> io::Result<String> {
let result = self.hasher.finalize();
Ok(format!("{:x}", result))
}
}

View File

@@ -11,6 +11,7 @@ use log::debug;
use rusqlite::Connection;
use crate::db::{self};
use crate::digest_engine::{DigestEngine, get_engine, DigestType};
use crate::modes::common::get_meta_from_env;
use chrono::Utc;
@@ -53,6 +54,10 @@ pub fn mode_save(
let compression_type = compression_type_opt.unwrap();
debug!("MAIN: Compression type: {}", compression_type);
// Create a new digest engine
let digest_type = DigestType::Sha256;
let mut digest_engine = get_engine(digest_type);
let mut item = db::Item {
id: None,
ts: Utc::now(),
@@ -140,6 +145,7 @@ pub fn mode_save(
stdout.write_all(&buffer[..n])?;
item_out.write_all(&buffer[..n])?;
digest_engine.update(&buffer[..n])?;
item.size = match item.size {
None => Some(n as i64),
Some(prev_n) => Some(prev_n + n as i64),
@@ -149,6 +155,10 @@ pub fn mode_save(
stdout.flush()?;
item_out.flush()?;
// Finalize the digest and log the result
let digest = digest_engine.finalize()?;
debug!("DIGEST: {}", digest);
db::update_item(&conn, item.clone())?;