Files
catena/crates/bindings/Cargo.toml
T
funkpower 18cc217c0d bindings: what a book says about itself, and what the register says back
book-pipeline reaches for colophon and bibfetch on every book it repairs.
Shelling out would mean a process per book per tool across five thousand
books, and parsing back the JSON it is about to parse anyway.

bibfetch's fetch loop lived in main.rs, so binding it meant either
lifting it or writing a second one. A second implementation of 'which
register answers about this kind of identifier, and in what order' would
drift from the first, and the copy nobody runs from a terminal would
drift silently. It is now bibfetch::ask, and the command line calls it
too — verified by running the CLI before and after and diffing.

fetch_identifier releases the GIL around the request. It is the only
function here that opens a socket, and holding the interpreter for the
length of an HTTP call would stop every other thread in it.

bibfetch is optional and only the python feature turns it on: its HTTP
client does not build for wasm32, and an unconditional dependency would
have taken the JavaScript package down with it.
2026-09-21 10:20:24 -04:00

81 lines
2.8 KiB
TOML

[package]
name = "catena"
description = "The catena libraries behind one surface, for calling in process rather than as a subprocess."
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
# wasm-pack ships a wasm-opt older than the WebAssembly rustc now emits, and
# it rejects the module rather than assuming the features are allowed. Naming
# them keeps the optimisation instead of turning it off; every one is years
# old and in every runtime that matters.
[package.metadata.wasm-pack.profile.release]
wasm-opt = [
"-O",
"--enable-bulk-memory",
"--enable-nontrapping-float-to-int",
"--enable-sign-ext",
"--enable-mutable-globals",
"--enable-reference-types",
]
[lib]
name = "catena"
path = "src/lib.rs"
# `cdylib` for the bindings, `rlib` so the workspace can still depend on it.
crate-type = ["cdylib", "rlib"]
[dependencies]
booksniff.workspace = true
bibclean.workspace = true
colophon.workspace = true
chunkmd.workspace = true
citefind.workspace = true
corpus-core.workspace = true
idnorm.workspace = true
cuekit.workspace = true
cuepack.workspace = true
cueseg.workspace = true
mdscrub.workspace = true
mdsplit.workspace = true
rrf.workspace = true
seriesof.workspace = true
serde.workspace = true
serde_json.workspace = true
textkit.workspace = true
pyo3 = { workspace = true, optional = true }
# Only the Python build gets this. bibfetch is the one tool here that opens a
# socket, and its HTTP client does not build for wasm32 — so a dependency that
# is unconditional would take the JavaScript package down with it.
bibfetch = { workspace = true, optional = true }
# The JavaScript build. Only ever compiled for a wasm32 target; on any other
# the module is compiled out and these sit unused.
wasm-bindgen = { workspace = true, optional = true }
serde-wasm-bindgen = { workspace = true, optional = true }
[features]
# Only maturin turns this on. pyo3's extension-module feature leaves the
# Python symbols to be resolved by the interpreter at load time, so an
# ordinary `cargo build` would fail to link if it were on by default.
python = ["dep:pyo3", "dep:bibfetch"]
# The C ABI. Off by default so an ordinary build does not also export a
# hundred symbols nobody asked for.
capi = []
# JavaScript and TypeScript, through WebAssembly.
wasm = ["dep:wasm-bindgen", "dep:serde-wasm-bindgen"]
# Not `workspace = true`. The workspace forbids unsafe, and a C ABI is unsafe
# by definition: it takes raw pointers from a caller this cannot see. The
# allowance is the narrowest thing that compiles — every `unsafe` in this
# crate is in `src/capi.rs`, and `unsafe_op_in_unsafe_fn` keeps each one
# spelled out rather than inherited from the function signature.
[lints.rust]
unsafe_code = "allow"
unsafe_op_in_unsafe_fn = "deny"
missing_docs = "warn"