Read title, author, subject, keywords, producer, creator and timestamps from any PDF's document-information dictionary.
use pdfluent::prelude::*;
fn main() -> Result<()> {
let doc = PdfDocument::open("report.pdf")?;
let meta = doc.metadata();
println!("title: {:?}", meta.title);
println!("author: {:?}", meta.author);
println!("subject: {:?}", meta.subject);
println!("keywords: {:?}", meta.keywords);
println!("producer: {:?}", meta.producer);
println!("creator: {:?}", meta.creator);
println!("created: {:?}", meta.creation_date);
println!("modified: {:?}", meta.modification_date);
Ok(())
}Open the document. Metadata is cached on the PdfDocument and read lazily from the Info dictionary on first access.
use pdfluent::prelude::*;
let doc = PdfDocument::open("report.pdf")?;metadata() returns a Metadata struct — a plain snapshot with public fields. There's no Result to unwrap for reads; missing entries surface as None / empty Vec.
let meta = doc.metadata();
println!("title = {:?}", meta.title);
println!("author = {:?}", meta.author);Metadata exposes title, author, subject, keywords (Vec<String>), producer, creator, creation_date and modification_date. Dates are PDF D-format strings (e.g. "D:20260421103000+02'00'") — parse them through your preferred date library if you need a DateTime.
let meta = doc.metadata();
if let Some(ref t) = meta.title { println!("T: {}", t); }
if let Some(ref a) = meta.author { println!("A: {}", a); }
for k in &meta.keywords { println!("K: {}", k); }Loop over files. Dropping the document at the end of each iteration keeps memory bounded across large batches.
use pdfluent::prelude::*;
use std::fs;
for entry in fs::read_dir("./inbox")? {
let path = entry?.path();
if path.extension().map(|e| e == "pdf").unwrap_or(false) {
match PdfDocument::open(&path) {
Ok(doc) => {
let m = doc.metadata();
println!(
"{}: {} — {}",
path.display(),
m.title.as_deref().unwrap_or("(no title)"),
m.author.as_deref().unwrap_or("(no author)"),
);
}
Err(e) => eprintln!("{}: {}", path.display(), e),
}
}
}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.