Write Dublin Core, XMP Basic, and custom XMP metadata packets to a PDF. XMP metadata is readable by search engines, DAM systems, and archival tools.
use pdfluent::{PdfDocument, XmpMetadata};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut doc = PdfDocument::open("whitepaper.pdf")?;
let xmp = XmpMetadata::new()
.title("PDFluent Technical Whitepaper")
.creator("Engineering Team")
.description("Architecture overview of the PDFluent Rust SDK")
.subject(vec!["PDF", "Rust", "SDK"])
.rights("Copyright 2025 PDFluent")
.language("en-US");
doc.set_xmp_metadata(xmp)?;
doc.save("whitepaper_with_xmp.pdf")?;
Ok(())
}Add the pdfluent crate to Cargo.toml.
[dependencies]
pdfluent = "0.9"Load the document to which you want to add XMP metadata.
use pdfluent::PdfDocument;
let mut doc = PdfDocument::open("report.pdf")?;XmpMetadata provides setters for Dublin Core and XMP Basic properties. All fields are optional.
use pdfluent::XmpMetadata;
let xmp = XmpMetadata::new()
.title("Annual Report 2025")
.creator("Finance Department")
.description("Consolidated financial statements for fiscal year 2025")
.subject(vec!["Finance", "Annual Report", "2025"])
.publisher("Acme Corp")
.rights("All rights reserved")
.language("en-GB")
.creation_date("2025-03-01T09:00:00Z")
.modify_date("2025-04-14T15:30:00Z");Register a custom namespace to store application-specific metadata alongside the standard Dublin Core fields.
let xmp = xmp
.custom_namespace("http://ns.acme.com/pdf/1.0/", "acme")
.custom_property("acme:documentId", "DOC-2025-0042")
.custom_property("acme:department", "Legal")
.custom_property("acme:confidentiality", "Internal");set_xmp_metadata() serialises the XMP packet and embeds it in the PDF. Existing XMP metadata is replaced.
doc.set_xmp_metadata(xmp)?;
doc.save("report_with_xmp.pdf")?;
println!("XMP metadata written.");No JVM, no runtime, no DLL dependencies. Ships as a single native binary or WASM module.
Rust's ownership model prevents buffer overflows and use-after-free. No segfaults in PDF parsing.
Same code runs server-side, in Docker, on AWS Lambda, on Cloudflare Workers, or in the browser via WASM.