use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct EKey([u8; 16]);
impl EKey {
pub fn new(data: [u8; 16]) -> Self {
Self(data)
}
pub fn from_slice(data: &[u8]) -> Option<Self> {
if data.len() == 16 {
let mut key = [0u8; 16];
key.copy_from_slice(data);
Some(Self(key))
} else {
None
}
}
pub fn as_bytes(&self) -> &[u8; 16] {
&self.0
}
pub fn truncated(&self) -> [u8; 9] {
let mut truncated = [0u8; 9];
truncated.copy_from_slice(&self.0[0..9]);
truncated
}
pub fn bucket_index(&self) -> u8 {
self.0.iter().fold(0u8, |acc, &byte| acc ^ byte) & 0x0F
}
}
impl fmt::Display for EKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in &self.0 {
write!(f, "{byte:02x}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ArchiveLocation {
pub archive_id: u16,
pub offset: u64,
pub size: u32,
}
#[derive(Debug, Clone)]
pub struct IndexEntry {
pub ekey: EKey,
pub location: ArchiveLocation,
}
#[derive(Debug, Clone, Copy)]
pub struct SharedMemoryFlags {
pub is_ready: bool,
pub is_updating: bool,
pub needs_repair: bool,
}
#[derive(Debug, Default)]
pub struct StorageStats {
pub total_archives: u32,
pub total_indices: u32,
pub total_size: u64,
pub file_count: u64,
pub duplicate_count: u64,
pub compression_ratio: f32,
}
#[derive(Debug, Clone)]
pub struct CascConfig {
pub data_path: std::path::PathBuf,
pub max_archive_size: u64,
pub use_memory_mapping: bool,
pub cache_size_mb: u32,
pub read_only: bool,
}
impl Default for CascConfig {
fn default() -> Self {
Self {
data_path: std::path::PathBuf::from("Data"),
max_archive_size: 1024 * 1024 * 1024, use_memory_mapping: true,
cache_size_mb: 256,
read_only: false,
}
}
}