use std::fmt;
use std::io::BufRead;
use age::secrecy::SecretString;
use crate::builder;
use crate::encryption;
use crate::page::PageSize;
#[derive(Debug)]
pub enum PaperAgeError {
Encryption(String),
DocumentInit(String),
PdfCreation(String),
}
impl fmt::Display for PaperAgeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PaperAgeError::Encryption(msg) => write!(f, "Encryption failed: {msg}"),
PaperAgeError::DocumentInit(msg) => write!(f, "Document initialization failed: {msg}"),
PaperAgeError::PdfCreation(msg) => write!(f, "PDF creation failed: {msg}"),
}
}
}
impl std::error::Error for PaperAgeError {}
pub fn create_pdf(
title: String,
data: &mut dyn BufRead,
passphrase: &str,
notes_label: Option<String>,
skip_notes_line: Option<bool>,
page_size: Option<PageSize>,
grid: Option<bool>,
) -> Result<Vec<u8>, PaperAgeError> {
let notes_label = notes_label.unwrap_or_else(|| "Passphrase:".to_string());
let skip_notes_line = skip_notes_line.unwrap_or(false);
let page_size = page_size.unwrap_or(PageSize::A4);
let grid = grid.unwrap_or(false);
let passphrase_secret = SecretString::from(passphrase.to_owned());
let (_plaintext_len, encrypted) = encryption::encrypt_plaintext(data, passphrase_secret)
.map_err(|e| PaperAgeError::Encryption(e.to_string()))?;
let pdf = builder::Document::new(title, page_size)
.map_err(|e| PaperAgeError::DocumentInit(e.to_string()))?;
let bytes = pdf
.create_pdf(grid, notes_label, skip_notes_line, encrypted)
.map_err(|e| PaperAgeError::PdfCreation(e.to_string()))?;
Ok(bytes)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_pdf_defaults() {
let result = create_pdf(
"Test Document".to_string(),
&mut &b"hello world"[..],
"passphrase",
None,
None,
None,
None,
);
assert!(result.is_ok());
let bytes = result.unwrap();
assert!(!bytes.is_empty());
}
#[test]
fn test_create_pdf_with_options() {
let result = create_pdf(
"Custom Document".to_string(),
&mut &b"secret data"[..],
"hunter2",
Some("Recovery key:".to_string()),
Some(true),
Some(PageSize::Letter),
Some(true),
);
assert!(result.is_ok());
}
#[test]
fn test_create_pdf_empty_data() {
let result = create_pdf(
"Empty".to_string(),
&mut &b""[..],
"passphrase",
None,
None,
None,
None,
);
assert!(result.is_ok());
}
#[test]
fn test_error_display() {
assert_eq!(
PaperAgeError::Encryption("bad key".to_string()).to_string(),
"Encryption failed: bad key"
);
assert_eq!(
PaperAgeError::DocumentInit("missing font".to_string()).to_string(),
"Document initialization failed: missing font"
);
assert_eq!(
PaperAgeError::PdfCreation("QR too large".to_string()).to_string(),
"PDF creation failed: QR too large"
);
}
}