| name | pdfium-impl-document-features |
| description | Use when reading PDF document metadata (title, author, dates), extracting or creating embedded file attachments, inspecting permission flags, or reading digital signatures with pdfium-render. Prevents guessing wrong permission method names, expecting metadata or signature write APIs that do not exist, deleting attachments by ascending index, and treating permission flags as enforcement. Covers PdfMetadata, PdfAttachments, PdfPermissions, PdfSignatures, the read-only-versus-writable asymmetry, and the 0.5.1 to 0.9.x version history. Keywords: pdfium-render metadata, PDF title author, PdfMetadata, get PdfDocumentMetadataTagType, PDF attachments, embedded files, PdfAttachments, create_attachment_from_bytes, delete_at_index, extract attachment, PDF permissions, PdfPermissions, can_print_high_quality, can_modify_document_content, digital signature, PdfSignatures, PdfSignature, signing_date, read PDF metadata in Rust, how do I get the PDF author, is this PDF signed
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires pdfium-render 0.8,0.9. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
pdfium-impl-document-features
Work with the four document-level feature collections in pdfium-render:
metadata, embedded attachments, permission flags, and digital signatures. Each
hangs off a PdfDocument handle.
Scope: document-level features. For page content see pdfium-syntax-pages and
pdfium-impl-page-objects-edit. For bookmarks, links, and destinations see
pdfium-impl-navigation. For saving edits see pdfium-impl-saving.
Default API surface is 0.9.x. All four collections predate 0.8.x and are fully
available in both the 0.8.x and 0.9.x lines.
The one rule that dominates this area
Three of the four collections are READ-ONLY. Only attachments can be written.
| Collection | Accessor | Writable? |
|---|
| Metadata | document.metadata() | NO. Read-only, no setters. |
| Attachments | document.attachments() / attachments_mut() | YES. Create and delete. |
| Permissions | document.permissions() | NO. Read-only. |
| Signatures | document.signatures() | NO. Read existing only. |
ONLY attachments has a _mut() accessor. There is no metadata_mut(),
permissions_mut(), or signatures_mut(). pdfium-render does not write
metadata, does not change permissions, and does not create signatures.
Quick Reference
Metadata
| Goal | Call | Returns |
|---|
| Count tags | metadata.len() | usize |
| Read one tag | metadata.get(PdfDocumentMetadataTagType::Title) | Option<PdfDocumentMetadataTag> |
| Read all tags | metadata.iter() | iterator of PdfDocumentMetadataTag |
| Tag kind | tag.tag_type() | PdfDocumentMetadataTagType |
| Tag string | tag.value() | &str |
PdfDocumentMetadataTagType has exactly eight variants: Title, Author,
Subject, Keywords, Creator, Producer, CreationDate,
ModificationDate. There is NO Trapped variant. get() returns None when
a tag is absent.
Attachments
| Goal | Call | Returns |
|---|
| Count | attachments.len() | PdfAttachmentIndex |
| Get one | attachments.get(index) | Result<PdfAttachment, PdfiumError> |
| Iterate | attachments.iter() | iterator of PdfAttachment |
| Create from bytes | attachments_mut().create_attachment_from_bytes(name, &[u8]) | Result<PdfAttachment, PdfiumError> |
| Create from file | attachments_mut().create_attachment_from_file(name, path) | Result<PdfAttachment, PdfiumError> |
| Create from reader | attachments_mut().create_attachment_from_reader(name, reader) | Result<PdfAttachment, PdfiumError> |
| Delete | attachments_mut().delete_at_index(index) | Result<(), PdfiumError> |
| Attachment name | attachment.name() | String |
| Attachment size | attachment.len() | usize |
| Extract to memory | attachment.save_to_bytes() | Result<Vec<u8>, PdfiumError> |
| Extract to disk | attachment.save_to_file(path) | Result<(), PdfiumError> |
Permissions
Every getter returns Result<bool, PdfiumError> (or
Result<PdfSecurityHandlerRevision, PdfiumError> for the revision).
security_handler_revision can_print_high_quality
can_print_only_low_quality can_assemble_document
can_modify_document_content can_extract_text_and_graphics
can_fill_existing_interactive_form_fields
can_create_new_interactive_form_fields
can_add_or_modify_text_annotations
PdfSecurityHandlerRevision has four variants: Unprotected, Revision2,
Revision3, Revision4.
Signatures
| Goal | Call | Returns |
|---|
| Count | signatures.len() | PdfSignatureIndex |
| Get one | signatures.get(index) | Result<PdfSignature, PdfiumError> |
| Iterate | signatures.iter() | iterator of PdfSignature |
| Raw blob | signature.bytes() | Vec<u8> |
| Signing reason | signature.reason() | Option<String> |
| Signing date | signature.signing_date() | Option<String> |
| MDP level | signature.modification_detection_permission() | Result<PdfSignatureModificationDetectionPermission, PdfiumError> |
PdfSignatureModificationDetectionPermission has three variants: Mdp1,
Mdp2, Mdp3.
Full signatures and version annotations: references/methods.md.
Patterns
Condensed patterns below. Complete runnable code is in references/examples.md.
Pattern 1: Read metadata
let document = pdfium.load_pdf_from_file("doc.pdf", None)?;
let metadata = document.metadata();
for tag in metadata.iter() {
println!("{:?} = {}", tag.tag_type(), tag.value());
}
if let Some(author) = metadata.get(PdfDocumentMetadataTagType::Author) {
println!("Author: {}", author.value());
}
CreationDate and ModificationDate values are raw, UNPARSED PDF date strings
in D:YYYYMMDDHHmmSS format. Parse them yourself if a typed date is needed.
Pattern 2: Extract attachments
for attachment in document.attachments().iter() {
let data = attachment.save_to_bytes()?;
println!("{}: {} bytes", attachment.name(), data.len());
}
PdfAttachment has no bytes() accessor. Extraction goes through
save_to_bytes() (memory) or save_to_file() (disk).
Pattern 3: Create an attachment
let mut document = pdfium.load_pdf_from_file("doc.pdf", None)?;
document
.attachments_mut()
.create_attachment_from_bytes("notes.txt", b"payload")?;
document.save_to_file("doc-with-attachment.pdf")?;
Creation needs &mut PdfDocument via attachments_mut(). The new attachment
lives in memory until the document is saved. See pdfium-impl-saving.
Pattern 4: Delete attachments
let count = document.attachments().len();
for index in (0..count).rev() {
document.attachments_mut().delete_at_index(index)?;
}
document.save_to_file("doc-cleaned.pdf")?;
delete_at_index is the ONLY deletion method. Deleting shifts every later index
down by one, so deleting multiple attachments ALWAYS goes from the highest index
downward.
Pattern 5: Query permissions
let perms = document.permissions();
println!("print HQ: {:?}", perms.can_print_high_quality());
println!("modify content: {:?}", perms.can_modify_document_content());
Pattern 6: Read signatures
for signature in document.signatures().iter() {
println!("reason: {:?}, signed: {:?}",
signature.reason(), signature.signing_date());
}
PdfSignatures is read-only. There is no signature-creation API and no
cryptographic verification. The signer identity lives inside the bytes()
PKCS#7 blob, which a separate cryptography crate must parse.
Permission flags are reported, not enforced
PdfPermissions getters REPORT the flags stored in the document. They do NOT
gate any pdfium-render operation. can_modify_document_content() returning
false does not stop attachments_mut(), annotations_mut(), or any edit
call. To respect a permission, check the flag and branch in your own code
BEFORE calling an edit method.
Common mistakes
| Mistake | Correct approach |
|---|
metadata().set_title(...) | metadata is read-only; no setters exist |
perms.can_print() | use can_print_high_quality + can_print_only_low_quality |
perms.can_copy_or_extract_text() | the name is can_extract_text_and_graphics |
if let Some(a) = attachments.get(0) | get returns Result, not Option |
delete_attachment(...) | only delete_at_index(index) exists |
| Deleting attachments by ascending index | iterate (0..count).rev() |
| Create attachment, drop document | save with save_to_file / save_to_bytes |
attachment.bytes() | use save_to_bytes() / save_to_file() |
signature.signer() | not exposed; parse the bytes() PKCS#7 blob |
signatures_mut() to create a signature | no creation API; signatures are read-only |
Each mistake is explained with root cause and fix in
references/anti-patterns.md.
Reference files
references/methods.md: complete API signatures with version annotations.
references/examples.md: working, verified Rust examples.
references/anti-patterns.md: real failures, why they fail, and the fix.
Related skills
pdfium-syntax-document-loading: loading the document these features hang off.
pdfium-impl-navigation: bookmarks, links, and destinations.
pdfium-impl-saving: persisting attachment create and delete changes.
pdfium-impl-form-fields: interactive form fields (a separate feature).
pdfium-errors-runtime: handling PdfiumError from these calls.