use std::error::Error;
use std::path::PathBuf;
use clap::Parser;
use vios_core::build_info;
#[cfg(feature = "pdf")]
use {
std::io::{self, Read},
std::path::Path,
vios_core::vault::pdf_exporter::export_vault_to_pdf,
};
#[cfg(feature = "boot-cli")]
use vios_core::cli::boot::BootCli;
#[derive(Parser, Debug)]
#[command(
name = "pdf_exporter_main",
version,
about = "Export a VIOS vault to PDF"
)]
struct Args {
#[cfg(feature = "boot-cli")]
#[command(flatten)]
boot: BootCli,
#[arg(value_name = "VAULT")]
vault: Option<PathBuf>,
#[arg(long, value_name = "PDF_OUT")]
pdf_out: Option<PathBuf>,
#[arg(long)]
password_from_env: bool,
#[arg(long)]
password_stdin: bool,
}
#[cfg(not(feature = "pdf"))]
fn main() -> Result<(), Box<dyn Error>> {
build_info::print_banner();
eprintln!("โ PDF feature is disabled. Rebuild with `--features pdf`.");
std::process::exit(2);
}
#[cfg(feature = "pdf")]
fn main() -> Result<(), Box<dyn Error>> {
build_info::print_banner();
let args = Args::parse();
#[cfg(feature = "boot-cli")]
{
let _ = &args.boot;
}
let vault_path = args.vault.clone().ok_or("Missing <VAULT> argument")?;
let out_path = args
.pdf_out
.clone()
.unwrap_or_else(|| default_pdf_out_path(&vault_path));
let password = get_password(&args)?;
let vault_str = vault_path.to_str().ok_or("Vault path is not valid UTF-8")?;
let out_str = out_path.to_str().ok_or("Output path is not valid UTF-8")?;
match export_vault_to_pdf(vault_str, password.trim(), out_str) {
Ok(()) => {
println!("โ
Exported to {}", out_path.display());
Ok(())
}
Err(e) => {
eprintln!("โ Error: {e}");
std::process::exit(1);
}
}
}
#[cfg(feature = "pdf")]
fn default_pdf_out_path(vault: &Path) -> PathBuf {
let mut out = vault.to_path_buf();
let stem = vault
.file_stem()
.and_then(|s| s.to_str())
.unwrap_or("vault_export");
out.set_file_name(format!("{stem}.pdf"));
out
}
#[cfg(feature = "pdf")]
fn get_password(args: &Args) -> Result<String, Box<dyn Error>> {
if args.password_from_env {
let p = std::env::var("VIOS_PASSWORD")
.map_err(|_| "VIOS_PASSWORD not set (use --password-from-env or omit the flag)")?;
return Ok(p);
}
if args.password_stdin {
let mut buf = String::new();
io::stdin().read_to_string(&mut buf)?;
return Ok(buf);
}
let p = rpassword::prompt_password("Enter password: ")?;
Ok(p)
}