use std::collections::HashMap;
use std::fmt;
pub type Md5Hash = [u8; 16];
pub type Id16 = [u8; 16];
#[derive(Debug, Clone)]
pub struct Par2FileSet {
pub recovery_set_id: Id16,
pub slice_size: u64,
pub files: HashMap<Id16, Par2File>,
pub recovery_block_count: u32,
pub creator: Option<String>,
}
#[derive(Debug, Clone)]
pub struct Par2File {
pub file_id: Id16,
pub hash: Md5Hash,
pub hash_16k: Md5Hash,
pub size: u64,
pub filename: String,
pub slices: Vec<SliceChecksum>,
}
#[derive(Debug, Clone, Copy)]
pub struct SliceChecksum {
pub md5: Md5Hash,
pub crc32: u32,
}
#[derive(Debug)]
pub struct VerifyResult {
pub intact: Vec<VerifiedFile>,
pub damaged: Vec<DamagedFile>,
pub missing: Vec<MissingFile>,
pub recovery_blocks_available: u32,
pub repair_possible: bool,
}
impl VerifyResult {
pub fn all_correct(&self) -> bool {
self.damaged.is_empty() && self.missing.is_empty()
}
pub fn blocks_needed(&self) -> u32 {
let damaged_blocks: u32 = self.damaged.iter().map(|d| d.damaged_block_count).sum();
let missing_blocks: u32 = self.missing.iter().map(|m| m.block_count).sum();
damaged_blocks + missing_blocks
}
}
#[derive(Debug)]
pub struct VerifiedFile {
pub filename: String,
pub size: u64,
}
#[derive(Debug)]
pub struct DamagedFile {
pub filename: String,
pub size: u64,
pub damaged_block_count: u32,
pub total_block_count: u32,
pub damaged_block_indices: Vec<u32>,
}
#[derive(Debug)]
pub struct MissingFile {
pub filename: String,
pub expected_size: u64,
pub block_count: u32,
}
impl fmt::Display for VerifyResult {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.all_correct() {
write!(f, "All {} files correct", self.intact.len())
} else {
write!(
f,
"{} intact, {} damaged, {} missing — {} blocks needed, {} available",
self.intact.len(),
self.damaged.len(),
self.missing.len(),
self.blocks_needed(),
self.recovery_blocks_available,
)
}
}
}