use crate::JisLevel;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Manifest {
pub tbz_version: u8,
pub block_count: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub signing_key: Option<String>,
pub blocks: Vec<BlockEntry>,
pub structure: ArchiveStructure,
pub total_uncompressed_size: u64,
pub max_nesting_depth: u8,
pub capabilities: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BlockEntry {
pub index: u32,
pub block_type: String,
pub compressed_size: u64,
pub uncompressed_size: u64,
pub jis_level: JisLevel,
pub description: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ArchiveStructure {
Flat,
Deep { max_depth: u8 },
}
impl Manifest {
pub fn new() -> Self {
Self {
tbz_version: crate::VERSION,
block_count: 1, signing_key: None,
blocks: Vec::new(),
structure: ArchiveStructure::Flat,
total_uncompressed_size: 0,
max_nesting_depth: 0,
capabilities: Vec::new(),
}
}
pub fn set_signing_key(&mut self, verifying_key: &ed25519_dalek::VerifyingKey) {
let hex: String = verifying_key.to_bytes().iter().map(|b| format!("{:02x}", b)).collect();
self.signing_key = Some(hex);
}
pub fn get_verifying_key(&self) -> Option<ed25519_dalek::VerifyingKey> {
let hex = self.signing_key.as_ref()?;
let bytes: Vec<u8> = (0..hex.len())
.step_by(2)
.filter_map(|i| u8::from_str_radix(&hex[i..i + 2], 16).ok())
.collect();
if bytes.len() != 32 {
return None;
}
let mut key_bytes = [0u8; 32];
key_bytes.copy_from_slice(&bytes);
ed25519_dalek::VerifyingKey::from_bytes(&key_bytes).ok()
}
pub fn add_block(&mut self, entry: BlockEntry) {
self.total_uncompressed_size += entry.uncompressed_size;
self.blocks.push(entry);
self.block_count = self.blocks.len() as u32 + 1; }
pub fn max_jis_level(&self) -> JisLevel {
self.blocks.iter().map(|b| b.jis_level).max().unwrap_or(0)
}
}
impl Default for Manifest {
fn default() -> Self {
Self::new()
}
}