unparser-shared 0.12.0

Shared plumbing for the un* document extraction family — C-ABI conventions today; markdown refine and VLM/AI capabilities land as opt-in features
Documentation
[package]
name = "unparser-shared"
version = "0.12.0"
edition = "2021"
authors = ["iyulab"]
license = "MIT"
description = "Shared plumbing for the un* document extraction family — C-ABI conventions today; markdown refine and VLM/AI capabilities land as opt-in features"
repository = "https://github.com/iyulab/unparser-shared"
homepage = "https://github.com/iyulab/unparser-shared"
documentation = "https://docs.rs/unparser-shared"
readme = "README.md"
keywords = ["ffi", "c-abi", "error-handling", "document", "extraction"]
categories = ["development-tools::ffi", "api-bindings"]
rust-version = "1.88"

[package.metadata.docs.rs]
all-features = true

[features]
default = []
# Lossless, idempotent markdown shape-refinement. Off by default so the
# always-linked crate root stays dependency-free; a caller that never
# touches `refine` never pulls in pulldown-cmark.
refine = ["dep:pulldown-cmark", "dep:pulldown-cmark-to-cmark"]

# VLM-based image understanding + AI-assisted markdown refine. Brings a
# network stack, so — unlike `refine` — this is also excluded from the wasm
# CI job (see .github/workflows/ci.yml): a native HTTP client does not build
# for wasm32-unknown-unknown, and that is a design decision, not a gap.
ai = ["dep:ureq", "dep:serde", "dep:serde_json", "dep:base64", "dep:thiserror"]

# The family's command-line tools: the update notice (once a day at most, off by flag,
# environment, CI or a non-terminal stderr) and the `update` command's self-replacement from
# GitHub releases. For the `*-cli` crates only — never enabled by a library build.
cli-update = ["dep:self_update", "dep:self-replace", "dep:tempfile", "dep:semver", "dep:colored"]

# The crate root (ffi/kind/scaffold) is linked unconditionally by three published
# cdylibs, so it stays dependency-free — a dependency here is a dependency in all
# of them. Optional capabilities (refine, ai) each bring their own dependency
# behind their own feature flag instead.
[dependencies]
pulldown-cmark = { version = "0.13", default-features = false, optional = true }
pulldown-cmark-to-cmark = { version = "22", optional = true }
# `default-features = false` drops gzip/cookie-jar/etc — this feature wants only
# a TLS-capable transport and JSON (de)serialization, kept as narrow as ureq allows.
ureq = { version = "3.4", default-features = false, features = ["rustls", "json"], optional = true }
serde = { version = "1", features = ["derive"], optional = true }
serde_json = { version = "1", optional = true }
base64 = { version = "0.23", optional = true }
# Family convention — unpdf/undoc/unhwp's error.rs all use it already.
thiserror = { version = "2.0", optional = true }
# `cli-update`: the release client the three CLIs used, on ureq (the `ai` feature's HTTP client)
# rather than its default reqwest + tokio.
self_update = { version = "1.3", default-features = false, features = ["ureq", "rustls", "github", "progress-bar", "archive-zip", "archive-tar", "compression-tar-gz", "compression-zip-deflate"], optional = true }
self-replace = { version = "1.5", optional = true }
tempfile = { version = "3", optional = true }
semver = { version = "1.0", optional = true }
colored = { version = "3.1", optional = true }

[dev-dependencies]
proptest = "1"
# A CommonMark parser to read back what the `markdown` helpers write (tests only — the crate
# root stays dependency-free).
pulldown-cmark = { version = "0.13", default-features = false }
# A synchronous mock HTTP server for the `ai` feature's integration tests.
# Chosen over httpmock/wiremock specifically because both pull in tokio —
# this crate's design goal of never propagating an async runtime applies to
# dev-dependencies too, not just to what ships to consumers.
tiny_http = "0.12"

[[test]]
name = "refine_golden"
path = "tests/refine_golden.rs"
required-features = ["refine"]

[[test]]
name = "refine_roundtrip_properties"
path = "tests/refine_roundtrip_properties.rs"
required-features = ["refine"]

[[test]]
name = "ai_image_understanding"
path = "tests/ai_image_understanding.rs"
required-features = ["ai"]

[[test]]
name = "ai_refine"
path = "tests/ai_refine.rs"
required-features = ["ai"]

[lints.rust]
missing_docs = "deny"
unsafe_op_in_unsafe_fn = "deny"