harumi 1.4.4

Pure-Rust PDF — CJK font embedding (Chinese/Japanese/Korean), OCR text overlay, text extraction, HTML→PDF, page merge/split. WASM-ready, zero C deps.
Documentation
use std::fmt;

/// Errors returned by harumi operations.
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
    /// A file system or stream I/O error.
    Io(std::io::Error),

    /// A structural problem in the PDF (malformed object graph, missing key, etc.).
    Pdf(lopdf::Error),

    /// The font format is not supported. Only TrueType (`.ttf`) and OpenType (`.otf`) are supported.
    UnsupportedFontKind,

    /// The font binary could not be parsed.
    FontParse(String),

    /// The requested page number does not exist in the document.
    PageNotFound(u32),

    /// A [`FontHandle`](crate::FontHandle) obtained from a different `Document` was used.
    InvalidFont(u32),

    /// An image could not be decoded (requires the `image` feature).
    #[cfg(feature = "image")]
    ImageDecode(String),

    #[cfg(not(feature = "image"))]
    #[doc(hidden)]
    _ImageDecode,

    /// A caller-supplied parameter is invalid (e.g. NaN coordinate, zero-size box).
    InvalidInput(String),

    /// A character in `new_text` is not present in the embedded font's ToUnicode mapping.
    /// The font may be subsetted and no longer contain the required glyph.
    FontCharNotMapped { ch: char, font_name: String },

    /// The password provided for an encrypted PDF was incorrect.
    WrongPassword,

    /// A certificate or private key could not be parsed (requires the `digital-signature` feature).
    #[cfg(feature = "digital-signature")]
    InvalidCertificate(String),

    #[cfg(not(feature = "digital-signature"))]
    #[doc(hidden)]
    _InvalidCertificate,

    /// A private key could not be parsed (requires the `digital-signature` feature).
    #[cfg(feature = "digital-signature")]
    InvalidPrivateKey(String),

    #[cfg(not(feature = "digital-signature"))]
    #[doc(hidden)]
    _InvalidPrivateKey,

    /// PKCS#12 file could not be parsed (requires the `digital-signature` feature).
    #[cfg(feature = "digital-signature")]
    Pkcs12Parse(String),

    #[cfg(not(feature = "digital-signature"))]
    #[doc(hidden)]
    _Pkcs12Parse,

    /// Signature operation failed (requires the `digital-signature` feature).
    #[cfg(feature = "digital-signature")]
    SignatureFailed(String),

    #[cfg(not(feature = "digital-signature"))]
    #[doc(hidden)]
    _SignatureFailed,
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Error::Io(e) => write!(f, "I/O error: {}", e),
            Error::Pdf(e) => write!(f, "PDF error: {}", e),
            Error::UnsupportedFontKind => write!(
                f,
                "unsupported font kind: only TrueType (.ttf) and OpenType (.otf) are supported"
            ),
            Error::FontParse(msg) => write!(f, "font parse error: {}", msg),
            Error::PageNotFound(page) => write!(f, "page {} not found", page),
            Error::InvalidFont(handle) => write!(f, "font handle {} is invalid", handle),
            #[cfg(feature = "image")]
            Error::ImageDecode(msg) => write!(f, "image decode error: {}", msg),
            #[cfg(not(feature = "image"))]
            Error::_ImageDecode => unreachable!(),
            Error::InvalidInput(msg) => write!(f, "invalid input: {}", msg),
            Error::FontCharNotMapped { ch, font_name } => {
                write!(
                    f,
                    "char '{}' not found in font '{}' ToUnicode mapping; font may be subsetted",
                    ch, font_name
                )
            }
            Error::WrongPassword => write!(f, "wrong password for encrypted PDF"),
            #[cfg(feature = "digital-signature")]
            Error::InvalidCertificate(msg) => write!(f, "invalid certificate: {}", msg),
            #[cfg(not(feature = "digital-signature"))]
            Error::_InvalidCertificate => unreachable!(),
            #[cfg(feature = "digital-signature")]
            Error::InvalidPrivateKey(msg) => write!(f, "invalid private key: {}", msg),
            #[cfg(not(feature = "digital-signature"))]
            Error::_InvalidPrivateKey => unreachable!(),
            #[cfg(feature = "digital-signature")]
            Error::Pkcs12Parse(msg) => write!(f, "PKCS#12 parse error: {}", msg),
            #[cfg(not(feature = "digital-signature"))]
            Error::_Pkcs12Parse => unreachable!(),
            #[cfg(feature = "digital-signature")]
            Error::SignatureFailed(msg) => write!(f, "signature failed: {}", msg),
            #[cfg(not(feature = "digital-signature"))]
            Error::_SignatureFailed => unreachable!(),
        }
    }
}

impl std::error::Error for Error {}

impl From<std::io::Error> for Error {
    fn from(e: std::io::Error) -> Self {
        Error::Io(e)
    }
}

impl From<lopdf::Error> for Error {
    fn from(e: lopdf::Error) -> Self {
        Error::Pdf(e)
    }
}

/// Alias for `std::result::Result<T, harumi::Error>`.
pub type Result<T> = std::result::Result<T, Error>;