pdftract/crates/pdftract-core
jedarden 0a83ef9d93 fix(pdftract-15prh): fix LRU eviction test with valid 64-char opts hashes
The test_eviction_sweep_performance test was using opts hashes with
a ":<i>" suffix (e.g., "9b21c0ff...:<i>"), which exceeded the 64-character
limit. This caused parse_opts_hash_from_filename to skip these entries
during enumeration, resulting in zero cache size and no eviction.

Fixed by generating valid 64-character hex opts hashes using the last
4 characters for the counter (format: "{}{:04x}", base_hash[:60], i)).

All 17 LRU tests now pass, including:
- test_eviction_sweep_performance: evicts 1000 entries (100 MB) down to 40 MB (80% of 50 MB limit)
- test_concurrent_touches: 100 threads, no garbled records
- test_touch_performance: 1000 touches in < 100 ms
- test_current_size_performance: enumerate 1000 entries in < 1 s
- test_sentinel_rotation: rotates at 10 MB threshold

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 05:25:07 -04:00
..
examples feat(pdftract-mcp): add MCP server implementation changes 2026-05-23 03:09:56 -04:00
proptest-regressions/parser/lexer feat(pdftract-29z7b): implement unified diagnostic system + CLI commands 2026-05-22 22:38:31 -04:00
src fix(pdftract-15prh): fix LRU eviction test with valid 64-char opts hashes 2026-05-23 05:25:07 -04:00
tests fix(pdftract-2a6rk): fix xref.rs u64 literal overflow in proptest 2026-05-22 17:26:27 -04:00
Cargo.toml feat(pdftract-172kr): implement filesystem layout for cache directory 2026-05-23 04:40:25 -04:00
pdftract-core.cdx.json feat(pdftract-67tm8): implement MCP stdio transport with integration tests 2026-05-23 00:16:42 -04:00
README.md docs(pdftract-49f8): establish Cargo.lock policy and documentation 2026-05-20 18:13:14 -04:00

pdftract-core

The core Rust library for PDF text extraction. This crate provides the parsing, layout analysis, font encoding recovery, and text extraction primitives used by the CLI (pdftract-cli) and Python bindings (pdftract-py).

Cargo.lock Policy

This workspace checks in Cargo.lock at the repository root. This is unconventional for library crates—the Cargo Book historically suggested that only binary crates should check in lockfiles, allowing library consumers to resolve their own dependency versions.

pdftract departs from this convention for release reproducibility:

  1. SLSA Level 3 provenance requires that every milestone tag produces byte-identical artifacts across builds. Without a checked-in lockfile, two runs of cargo build on the same commit can resolve different transitive dependency versions, producing different binary hashes.

  2. Multi-output artifacts—this workspace produces Rust crates (pdftract-core, pdftract-cli), Python wheels (pdftract-py), and Docker images. All must be built from the same dependency tree.

  3. Supply-chain security—the lockfile pins checksums for all transitive dependencies, enabling cargo audit to detect yanked or compromised crates.

  4. Downstream consumers can still ignore the lockfile if needed. Cargo allows cargo build --frozen with a local lockfile override, or consumers can vendor the crate with their own dependency resolution.

The tradeoff—occasional merge conflicts when PRs update overlapping dependencies—is worth the guarantee of reproducible releases. See CONTRIBUTING.md for the lockfile-update workflow.

Modules

  • parser: PDF spec parsing (xref, trailer, object streams, indirect references)
  • font: Font encoding recovery, glyph name lookup, fingerprinting
  • layout: Page layout analysis, region segmentation, reading order
  • extract: Text extraction with provenance (bounding boxes, confidence scores)
  • ocr: Tesseract integration for raster pages

Usage

use pdftract_core::{extract_text, ExtractOptions};

let options = ExtractOptions::default();
let result = extract_text("document.pdf", &options)?;
println!("{}", result.text);