use std::io::Read;
use crate::error::PqfileError;
use crate::format::{
PqfHeader, PqfHeaderV4, PqfHeaderV7, PqfHeaderV8, NONCE_LEN, VERSION, VERSION_V3, VERSION_V4,
VERSION_V5, VERSION_V6, VERSION_V7, VERSION_V8, VERSION_V9,
};
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct RecipientInfo {
pub kem_variant: u16,
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub enum PqfHeaderInfo {
Single {
version: u8,
kem_variant: u16,
nonce: [u8; NONCE_LEN],
original_size: u64,
chunk_size: u32,
compression_algo: u8,
},
Multi {
recipients: Vec<RecipientInfo>,
nonce: [u8; NONCE_LEN],
original_size: u64,
},
AnonMulti {
recipients: Vec<RecipientInfo>,
nonce: [u8; NONCE_LEN],
original_size: u64,
},
AnonMultiV8 {
version: u8,
slot_count: usize,
nonce: [u8; NONCE_LEN],
original_size: u64,
},
}
#[must_use = "inspect result must be used"]
pub fn inspect_stream<R: Read>(reader: &mut R) -> Result<PqfHeaderInfo, PqfileError> {
let version = PqfHeader::read_magic_version(reader)?;
match version {
VERSION | VERSION_V3 | VERSION_V5 | VERSION_V6 => {
let h = PqfHeader::read_body(reader, version)?;
Ok(PqfHeaderInfo::Single {
version: h.version,
kem_variant: h.kem_variant,
nonce: h.nonce,
original_size: h.original_size,
chunk_size: h.chunk_size,
compression_algo: h.compression_algo,
})
}
VERSION_V4 => {
let h = PqfHeaderV4::read_body(reader)?;
Ok(PqfHeaderInfo::Multi {
recipients: h
.recipients
.iter()
.map(|r| RecipientInfo {
kem_variant: r.kem_variant,
})
.collect(),
nonce: h.nonce,
original_size: h.original_size,
})
}
VERSION_V7 => {
let h = PqfHeaderV7::read_body(reader)?;
Ok(PqfHeaderInfo::AnonMulti {
recipients: h
.recipients
.iter()
.map(|r| RecipientInfo {
kem_variant: r.kem_variant,
})
.collect(),
nonce: h.nonce,
original_size: h.original_size,
})
}
VERSION_V8 | VERSION_V9 => {
let h = PqfHeaderV8::read_body(reader)?;
Ok(PqfHeaderInfo::AnonMultiV8 {
version,
slot_count: h.recipients.len(),
nonce: h.nonce,
original_size: h.original_size,
})
}
v => Err(PqfileError::UnsupportedVersion(v)),
}
}