use thiserror::Error;
#[derive(Debug, Error)]
pub enum Error {
#[error("Form error: {0}")]
Form(#[from] FormError),
#[error("Signing error: {0}")]
Signing(#[from] SigningError),
#[error("Encryption error: {0}")]
Encryption(#[from] EncryptionError),
#[error("Watermark error: {0}")]
Watermark(#[from] WatermarkError),
#[error("Bookmark error: {0}")]
Bookmark(#[from] BookmarkError),
#[error("Annotation error: {0}")]
Annotation(#[from] AnnotationError),
#[error("PDF/A error: {0}")]
PdfA(#[from] PdfAError),
#[error("PDF/UA error: {0}")]
PdfUA(#[from] PdfUAError),
#[error("Invalid PDF: {0}")]
InvalidPdf(String),
#[error("Invalid parameter: {0}")]
InvalidParameter(String),
#[error("PDF operation error: {0}")]
PdfOperation(String),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("FFI error: {0}")]
Ffi(#[from] cxx::Exception),
}
#[derive(Debug, Error)]
pub enum FormError {
#[error(
"PDF form manipulation requires a commercial license. Purchase at: https://printwell.dev/pricing"
)]
RequiresLicense,
#[error("failed to initialize form builder: {0}")]
InitFailed(String),
#[error("failed to add {field_type} field '{name}': {reason}")]
AddFieldFailed {
field_type: &'static str,
name: String,
reason: String,
},
#[error("failed to build form: {0}")]
BuildFailed(String),
#[error("validation failed for field '{field}': {reason}")]
ValidationFailed {
field: String,
reason: String,
},
#[error("invalid field specification: {0}")]
InvalidSpec(String),
#[error("{0}")]
Operation(String),
}
#[derive(Debug, Error)]
pub enum SigningError {
#[error(
"Digital signing requires a commercial license. Purchase at: https://printwell.dev/pricing"
)]
RequiresLicense,
#[error("failed to load certificate: {0}")]
CertificateLoadFailed(String),
#[error("invalid certificate format: {0}")]
InvalidCertificate(String),
#[error("failed to prepare PDF for signing: {0}")]
PrepareFailed(String),
#[error("failed to create signature: {0}")]
SignatureFailed(String),
#[error("failed to embed signature in PDF: {0}")]
EmbedFailed(String),
#[error("no signer information found in signature")]
NoSignerInfo,
#[error("signature verification failed: {0}")]
VerificationFailed(String),
#[error("timestamp operation failed: {0}")]
TimestampFailed(String),
#[error("CMS operation failed: {0}")]
CmsFailed(String),
#[error("failed to extract signatures: {0}")]
ExtractionFailed(String),
#[error("{0}")]
Operation(String),
}
#[derive(Debug, Error)]
pub enum EncryptionError {
#[error(
"PDF encryption requires a commercial license. Purchase at: https://printwell.dev/pricing"
)]
RequiresLicense,
#[error("invalid password")]
InvalidPassword,
#[error("password too short (minimum {min} characters)")]
PasswordTooShort {
min: usize,
},
#[error("unsupported encryption algorithm: {0}")]
UnsupportedAlgorithm(String),
#[error("failed to encrypt PDF: {0}")]
EncryptFailed(String),
#[error("failed to decrypt PDF: {0}")]
DecryptFailed(String),
#[error("PDF is already encrypted")]
AlreadyEncrypted,
#[error("PDF is not encrypted")]
NotEncrypted,
#[error("{0}")]
Operation(String),
}
#[derive(Debug, Error)]
pub enum WatermarkError {
#[error("either text or image must be specified for watermark")]
NoContent,
#[error("cannot specify both text and image for watermark")]
BothContentTypes,
#[error("invalid image data: {0}")]
InvalidImage(String),
#[error("invalid opacity value {value}: must be between 0.0 and 1.0")]
InvalidOpacity {
value: f32,
},
#[error("invalid position: {0}")]
InvalidPosition(String),
#[error("failed to add watermark: {0}")]
AddFailed(String),
#[error("{0}")]
Operation(String),
}
#[derive(Debug, Error)]
pub enum BookmarkError {
#[error("invalid bookmark specification: {0}")]
InvalidSpec(String),
#[error("invalid page number {page}: document has {total} pages")]
InvalidPage {
page: u32,
total: u32,
},
#[error("failed to add bookmarks: {0}")]
AddFailed(String),
#[error("failed to extract bookmarks: {0}")]
ExtractFailed(String),
#[error("{0}")]
Operation(String),
}
#[derive(Debug, Error)]
pub enum AnnotationError {
#[error("invalid annotation type: {0}")]
InvalidType(String),
#[error("invalid rectangle bounds: {reason}")]
InvalidRect {
reason: String,
},
#[error("invalid color: {0}")]
InvalidColor(String),
#[error("failed to add annotations: {0}")]
AddFailed(String),
#[error("failed to list annotations: {0}")]
ListFailed(String),
#[error("failed to remove annotations: {0}")]
RemoveFailed(String),
#[error("{0}")]
Operation(String),
}
#[derive(Debug, Error)]
pub enum PdfAError {
#[error(
"PDF/A compliance features require a commercial license. Purchase at: https://printwell.dev/pricing"
)]
RequiresLicense,
#[error("invalid PDF/A level: {0}")]
InvalidLevel(String),
#[error("PDF/A validation failed: {error_count} errors, {warning_count} warnings")]
ValidationFailed {
error_count: usize,
warning_count: usize,
},
#[error("failed to add PDF/A metadata: {0}")]
MetadataFailed(String),
#[error("document has {count} compliance issues")]
ComplianceIssues {
count: usize,
},
#[error("{0}")]
Operation(String),
}
#[derive(Debug, Error)]
pub enum PdfUAError {
#[error(
"PDF/UA accessibility features require a commercial license. Purchase at: https://printwell.dev/pricing"
)]
RequiresLicense,
#[error("invalid PDF/UA level: {0}")]
InvalidLevel(String),
#[error("document missing required structure: {0}")]
MissingStructure(String),
#[error("accessibility issue: {category} - {description}")]
AccessibilityIssue {
category: String,
description: String,
},
#[error("failed to add PDF/UA metadata: {0}")]
MetadataFailed(String),
#[error("{0}")]
Operation(String),
}
impl From<String> for FormError {
fn from(s: String) -> Self {
Self::Operation(s)
}
}
impl From<String> for SigningError {
fn from(s: String) -> Self {
Self::Operation(s)
}
}
impl From<String> for EncryptionError {
fn from(s: String) -> Self {
Self::Operation(s)
}
}
impl From<String> for WatermarkError {
fn from(s: String) -> Self {
Self::Operation(s)
}
}
impl From<String> for BookmarkError {
fn from(s: String) -> Self {
Self::Operation(s)
}
}
impl From<String> for AnnotationError {
fn from(s: String) -> Self {
Self::Operation(s)
}
}
impl From<String> for PdfAError {
fn from(s: String) -> Self {
Self::Operation(s)
}
}
impl From<String> for PdfUAError {
fn from(s: String) -> Self {
Self::Operation(s)
}
}
pub type Result<T> = std::result::Result<T, Error>;