printwell-cli 0.1.11

Command-line tool for HTML to PDF conversion
Documentation
//! CLI implementation for printwell.

mod args;
mod commands;
mod utils;

use anyhow::{Context, Result};
use clap::{Parser, Subcommand};

pub use args::*;

#[derive(Parser)]
#[command(name = "printwell")]
#[command(about = "HTML to PDF conversion tool")]
#[command(version)]
struct Cli {
    #[command(subcommand)]
    command: Commands,

    /// Increase verbosity (-v, -vv, -vvv)
    #[arg(short, long, action = clap::ArgAction::Count, global = true)]
    verbose: u8,

    /// Suppress output
    #[arg(short, long, global = true)]
    quiet: bool,
}

#[derive(Subcommand)]
enum Commands {
    /// Convert HTML to PDF
    Convert(Box<ConvertArgs>),

    /// Add form fields to PDF
    #[cfg(feature = "forms")]
    Forms(FormsArgs),

    /// Sign a PDF document
    #[cfg(feature = "signing")]
    Sign(SignArgs),

    /// Verify PDF signatures
    #[cfg(feature = "signing")]
    Verify(VerifyArgs),

    /// List signature fields in a PDF
    #[cfg(feature = "signing")]
    ListFields(ListFieldsArgs),

    /// Encrypt a PDF with password protection
    #[cfg(feature = "encrypt")]
    Encrypt(EncryptArgs),

    /// Decrypt a password-protected PDF
    #[cfg(feature = "encrypt")]
    Decrypt(DecryptArgs),

    /// Add watermark to a PDF
    #[cfg(feature = "watermark")]
    Watermark(WatermarkArgs),

    /// Add or extract bookmarks from a PDF
    #[cfg(feature = "bookmarks")]
    Bookmarks(BookmarksArgs),

    /// Add, list, or remove annotations from a PDF
    #[cfg(feature = "annotations")]
    Annotate(AnnotateArgs),

    /// Validate PDF/A compliance
    #[cfg(feature = "pdfa")]
    PdfaValidate(PdfaValidateArgs),

    /// Add PDF/A metadata to a PDF
    #[cfg(feature = "pdfa")]
    PdfaConvert(PdfaConvertArgs),

    /// Validate PDF/UA accessibility compliance
    #[cfg(feature = "pdfua")]
    PdfuaValidate(PdfuaValidateArgs),

    /// Add PDF/UA accessibility metadata to a PDF
    #[cfg(feature = "pdfua")]
    PdfuaConvert(PdfuaConvertArgs),

    /// Convert multiple HTML files to PDF in batch
    ConvertBatch(ConvertBatchArgs),

    /// Display PDF/renderer information
    Info(InfoArgs),
}

fn setup_logging(verbose: u8, quiet: bool) {
    use tracing_subscriber::EnvFilter;

    if quiet {
        return;
    }

    let level = match verbose {
        0 => "warn",
        1 => "info",
        2 => "debug",
        _ => "trace",
    };

    tracing_subscriber::fmt()
        .with_env_filter(
            EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(level)),
        )
        .init();
}

/// Main entry point - called from lib.rs with converted args.
pub fn run(args: Vec<String>) -> Result<()> {
    let cli = Cli::parse_from(args);

    setup_logging(cli.verbose, cli.quiet);

    // Create tokio runtime for async operations
    let rt = tokio::runtime::Runtime::new().context("Failed to create async runtime")?;

    rt.block_on(async {
        match cli.command {
            Commands::Convert(args) => commands::convert(*args).await,
            #[cfg(feature = "forms")]
            Commands::Forms(args) => commands::forms(&args),
            #[cfg(feature = "signing")]
            Commands::Sign(args) => commands::sign(args),
            #[cfg(feature = "signing")]
            Commands::Verify(args) => commands::verify(&args),
            #[cfg(feature = "signing")]
            Commands::ListFields(args) => commands::list_fields(&args),
            #[cfg(feature = "encrypt")]
            Commands::Encrypt(args) => commands::encrypt(&args),
            #[cfg(feature = "encrypt")]
            Commands::Decrypt(args) => commands::decrypt(&args),
            #[cfg(feature = "watermark")]
            Commands::Watermark(args) => commands::watermark(args),
            #[cfg(feature = "bookmarks")]
            Commands::Bookmarks(args) => commands::bookmarks(&args),
            #[cfg(feature = "annotations")]
            Commands::Annotate(args) => commands::annotate(&args),
            #[cfg(feature = "pdfa")]
            Commands::PdfaValidate(args) => commands::pdfa_validate(&args),
            #[cfg(feature = "pdfa")]
            Commands::PdfaConvert(args) => commands::pdfa_convert(&args),
            #[cfg(feature = "pdfua")]
            Commands::PdfuaValidate(args) => commands::pdfua_validate(&args),
            #[cfg(feature = "pdfua")]
            Commands::PdfuaConvert(args) => commands::pdfua_convert(&args),
            Commands::ConvertBatch(args) => commands::convert_batch(args).await,
            Commands::Info(args) => commands::info(args).await,
        }
    })
}