use crate::error::Result;
use crate::EngineRouter;
#[derive(Debug, Clone)]
pub struct EmbedResult {
pub source_size: usize,
pub output_size: usize,
pub engine: String,
}
#[derive(Debug, Clone)]
pub struct ExtractResult {
pub source_size: usize,
pub payload_size: usize,
pub engine: String,
}
pub fn embed(source_data: &[u8], payload_data: &[u8]) -> Result<(Vec<u8>, EmbedResult)> {
let router = EngineRouter::new();
let engine = router.detect_engine(source_data)?;
let embedded_data = engine.embed(source_data, payload_data)?;
let result = EmbedResult {
source_size: source_data.len(),
output_size: embedded_data.len(),
engine: engine.format_name().to_string(),
};
Ok((embedded_data, result))
}
pub fn extract(source_data: &[u8]) -> Result<(Vec<u8>, ExtractResult)> {
let router = EngineRouter::new();
let engine = router.detect_engine(source_data)?;
let payload = engine.extract(source_data)?;
let result = ExtractResult {
engine: engine.format_name().to_string(),
payload_size: payload.len(),
source_size: source_data.len(),
};
Ok((payload, result))
}
#[cfg(test)]
mod tests {
use super::*;
fn create_minimal_pdf() -> Vec<u8> {
b"%PDF-1.4\n1 0 obj\n<<\n/Type /Catalog\n>>\nendobj\nxref\n0 1\n0000000000 65535 f\ntrailer\n<<\n/Size 1\n/Root 1 0 R\n>>\nstartxref\n73\n%%EOF".to_vec()
}
#[test]
fn test_embed() {
let source = create_minimal_pdf();
let payload = b"test message";
let result = embed(&source, payload);
assert!(result.is_ok());
let (embedded_data, metadata) = result.unwrap();
assert!(embedded_data.len() > source.len()); assert!(embedded_data.starts_with(b"%PDF"));
assert_eq!(metadata.engine, "PDF"); assert_eq!(metadata.source_size, 125); assert_eq!(metadata.output_size, 141); }
#[test]
fn test_extract() {
let source = create_minimal_pdf();
let original_payload = b"secret data";
let (embedded_data, _) = embed(&source, original_payload).unwrap();
let result = extract(&embedded_data);
assert!(result.is_ok());
let (extracted_payload, metadata) = result.unwrap();
assert_eq!(extracted_payload, original_payload);
assert_eq!(metadata.engine, "PDF"); assert_eq!(metadata.source_size, embedded_data.len()); assert_eq!(metadata.payload_size, 11); }
}