Expand description
Native (non-WASM) plugin support.
These plugins run as native Rust code for maximum performance. They implement the same interface as WASM plugins.
§Pass discrimination (issue #1166)
Plugins run in one of two passes — see the loader’s PluginPass
enum:
- Pre-booking synth pass: synthesizers like
auto_accountsanddocument_discoverythat inject directives the Early validator depends on (e.g.Opendirectives so account- presence checks see them). - Post-booking regular pass: transformations on already-
booked directives — most plugins, including the cost-spec-
reading ones (
implicit_prices,unrealized, etc.) that need to see filled-in per-unit values from the booker.
Each native plugin declares which pass it runs in by implementing
either SynthPlugin or RegularPlugin (both extend the base
NativePlugin trait). The registry holds two separately-typed
Vecs (Vec<Box<dyn SynthPlugin>> and Vec<Box<dyn RegularPlugin>>),
and the loader’s runner consults the typed registry for the
appropriate pass via NativePluginRegistry::find_synth /
NativePluginRegistry::find_regular. The returned trait
reference’s type matches the pass: find_synth can never return
a RegularPlugin and vice versa, so the dispatch site can’t
accidentally invoke a wrong-pass plugin even on a name collision.
§Where the discipline is enforced
The marker traits are intentionally not mutually exclusive at
the type level — SynthPlugin and RegularPlugin are empty
sub-traits of NativePlugin, and nothing in the type system
prevents a single type from implementing both. Exclusivity is
enforced by:
- Registry construction convention: each plugin is pushed
into exactly one of the two Vecs in
build_global_registry. - A pinned test (
test_registry_synth_and_regular_are_disjoint): iteratesregistry.iter()and asserts every plugin lives in exactly one Vec — CI catches a wrong-pass registration or a type that implements both markers and ends up in both Vecs.
The marker pair is therefore lighter than full type-level exclusivity (which would need negative trait bounds or a sealed pass-marker pattern that breaks object safety in our registry) — the cost is one assertion in CI instead of a compile error.
§Why a marker-trait pair rather than a single trait with a const
const PASS: PluginPass on the base trait would be cleaner if
consts were object-safe — but they aren’t, and the registry uses
trait objects (Box<dyn SynthPlugin> / Box<dyn RegularPlugin>)
for heterogeneous storage. The marker-pair approach gives the
dispatch-site type guarantee (described above) at the cost of one
extra empty impl line per plugin.
§WASM and Python plugins
Non-native plugins don’t implement NativePlugin and therefore
aren’t held in this registry. They’re dispatched by the loader
through path-based name resolution, run only in the post-booking
regular pass, and never carry a synth/regular marker at the type
level. Synth-pass semantics are a native-only concern.
Modules§
- utils
- Shared utility functions for native plugins.
Structs§
- Auto
Accounts Plugin - Plugin that auto-generates Open directives for accounts used without explicit open.
- Auto
TagPlugin - Plugin that automatically adds tags based on account patterns.
- BoxAccrual
Plugin - Plugin for splitting capital losses across multiple years.
- Capital
Gains Gain Loss Plugin - Plugin for classifying capital gains into gains/losses categories.
- Capital
Gains Long Short Plugin - Plugin for classifying capital gains into long/short term categories.
- Check
Average Cost Plugin - Plugin that validates reducing postings against the running average cost
for accounts opened with the
NONEbooking method. - Check
Closing Plugin - Plugin that inserts zero balance assertion when posting has
closing: TRUEmetadata. - Check
Commodity Plugin - Plugin that checks all used commodities are declared.
- Check
Drained Plugin - Plugin that inserts zero balance assertions when balance sheet accounts are closed.
- Close
Tree Plugin - Plugin that closes all descendant accounts when a parent account closes.
- Coherent
Cost Plugin - Plugin that ensures currencies are tracked consistently with cost or price-only.
- Commodity
Attr Plugin - Plugin that validates Commodity directives have required metadata attributes.
- Currency
Accounts Plugin - Plugin that auto-generates currency trading account postings.
- Document
Discovery Plugin - Plugin that auto-discovers document files from configured directories.
- Effective
Date Plugin - Plugin for handling effective dates on postings.
- Forecast
Plugin - Plugin for generating recurring forecast transactions.
- Generate
Base CcyPrices Plugin - Plugin for generating base currency prices.
- Implicit
Prices Plugin - Plugin that generates price entries from transaction postings.
- Leaf
Only Plugin - Plugin that errors when posting to non-leaf (parent) accounts.
- Native
Plugin Registry - Registry of built-in native plugins, split by pass.
- NoDuplicates
Plugin - Plugin that detects duplicate transactions based on structural hash.
- NoUnused
Plugin - Plugin that identifies accounts that are opened but never used.
- OneCommodity
Plugin - Plugin that enforces single commodity per account.
- Pedantic
Plugin - Meta-plugin that enables all strict validation plugins.
- Rename
Accounts Plugin - Plugin for renaming accounts using regex patterns.
- RxTxn
Plugin - Plugin for Regular Expected Transactions.
- Sell
Gains Plugin - Plugin that cross-checks declared gains against sale prices.
- Split
Expenses Plugin - Plugin for splitting expenses between multiple people.
- Unique
Prices Plugin - Plugin that enforces unique prices (one per commodity pair per day).
- Unrealized
Plugin - Plugin that calculates unrealized gains on positions.
- Valuation
Plugin - Plugin for tracking opaque fund values.
- Zerosum
Plugin - Plugin for matching zero-sum postings.
Constants§
- AUTO_
ACCOUNTS_ NAME - Name used by the registry, the loader (when emitting the implicit
synth-pass entry for
options.auto_accounts), and external callers. Kept as a constant so the three sites stay in sync. - DOCUMENT_
DISCOVERY_ NAME - Name passed to file-declared / extra-plugin lookups and used by the loader when emitting the synth-pass config entry. Kept as a constant so the registry, the loader, and the rustdoc stay in sync.
Traits§
- Native
Plugin - Base capability for native plugins. Both
SynthPluginandRegularPluginextend this — every native plugin has these three methods regardless of pass. - Regular
Plugin - Marker trait: a plugin that runs in the post-booking regular pass.
- Synth
Plugin - Marker trait: a plugin that runs in the pre-booking synth pass.
Functions§
- document_
discovery_ config - Build the
PluginInput::configJSON string for this plugin.