Skip to main content

Module registry

Module registry 

Source
Expand description

Format registry – read/write/check a crate::document::Doc by format name at runtime, plus register your own format plugins. Ported from ~/dev/omnist/omnist/registry.py (issue #31; see also the TypeScript port’s registry.ts for the same architecture-freedom call made there).

Python’s registry is a plain dict[str, Format] of arbitrary callables – genuine runtime plugin registration, exercised by tests/test_canonical.py::TestRegistry: a caller can register_format an arbitrary (name, read, write, check?) tuple at runtime and every Doc-level API that takes a format name (from_format/to_format/ check_format) transparently picks it up. A closed enum dispatch (the omnist-cli Fmt enum’s approach, or a match over the five builtins) can’t express “register a new format at runtime under an arbitrary name,” so this module reaches for the same dynamic-dispatch idiom Rust uses in place of Python’s first-class functions: Arc<dyn Fn(...) + Send + Sync> trait objects, keyed by name in an IndexMap behind an RwLock inside a OnceLock (this crate’s only piece of global mutable state). Arc (not Box) so get_format can hand back an owned, independently usable Format without holding the registry lock across the caller’s use of it – mirroring Python’s _LOCK-guarded dict lookup, which also releases the lock before the caller touches the returned Format.

§Uniform signatures across five differently-shaped codecs

crate::formats::json::write_json takes an extra indent: Option< usize> the other three format writers don’t, and crate::oml’s read_oml/write_oml operate on crate::document::RawNode rather than Doc directly (see oml.rs’s own module doc on why). The ReadFn/WriteFn the registry stores are Doc-in/Doc-out with no format-specific options, matching Python’s registry entries as actually invoked from this port’s zero-arg call sites (Python’s Doc.to_format forwards **o through, but nothing in the Python test suite or docs/api.md exercises that with the builtins, so this port keeps the simpler no-options signature and documents the gap here rather than silently reproducing untested surface). The five builtins are registered as thin wrapper closures around the existing per-format functions with their default options (indent: None, strict: false, no report requested for writers; Doc::from_raw/to_raw bridging OML’s RawNode shape) – get_format("json").read/.write are not literally read_json/write_json (Rust can’t express “the same fn item” through an Arc<dyn Fn> the way Python’s is can point at the same function object), but they call straight through with no other logic, matching Python’s actual invariant in spirit: no behavior is added or changed at the registry boundary.

§OML’s check_oml

Rust’s port had no check_oml before this issue – OML is lossless for every Doc (see oml.rs’s module doc: “no adjustment ever needed”), so nothing needed to call it. Python’s check_oml exists purely to satisfy the registry Format tuple’s fourth slot and always returns an empty WriteReport; this issue adds the same trivial function to oml.rs for the same reason (used only via the "oml" registry entry’s check).

Structs§

Format
A registered format: a name plus read/write callables and an optional check. Mirrors Python’s Format NamedTuple (name, read, write, check); a plugin registered with Format::new alone has no check, and crate::document::Doc::check_format errors cleanly (not a panic) if invoked on it – matching test_plugin_without_check_raises_on_check_format.

Functions§

formats
The names of all registered formats, sorted.
get_format
The registered Format for name. An OmnistError::Format if unknown, naming every currently-registered format name, sorted – mirrors Python’s get_format’s f"unknown format {name!r}; registered: {known}" message. Unlike Python, there is no "(none)" fallback for an empty registry: register_format only ever adds entries and the five builtins always register on first access (see builtins), so the registry can never actually be empty here – an untestable dead branch for that case was deliberately not carried over (playbook’s “unreachable dead code” gap classification), rather than kept under an unreachable coverage-ignore.
register_format
Register (or replace) a format plugin, usable everywhere a format name is accepted, including crate::document::Doc::from_format/to_format/ check_format.

Type Aliases§

CheckFn
Doc -> WriteReport check callable; simulates a write without producing output.
ReadFn
text -> Doc reader callable.
WriteFn
Doc -> text writer callable.