Skip to main content

confium_api/
registry.rs

1//! Link-time registry of interfaces declared in a plugin crate.
2//!
3//! Each `#[plugin_interface(name = "...", version = N)]` attribute
4//! submits a [`RegisteredInterface`] entry to this registry via
5//! `inventory`. The `#[export]` macro iterates the registry at runtime
6//! (inside `cfmp_query_interfaces`) to build the packed
7//! `name\0version\0` payload the loader parses — so plugin authors no
8//! longer need to repeat the interface list in the `#[export]`
9//! attribute.
10//!
11//! This is the plugin-side mirror of `confium_core::ffi::registry`: the
12//! core registry maps interface names to builder functions; this
13//! registry maps interface names to the versions a single plugin
14//! advertises.
15
16/// One `(name, version)` pair that a plugin's `#[plugin_interface]`
17/// attribute declared. Collected at link time via `inventory`.
18pub struct RegisteredInterface {
19    /// Wire name the plugin advertises via `cfmp_query_interfaces`.
20    /// This is the name the loader's registry (`PluginInterfaceKind`)
21    /// recognizes — e.g. `"hash"`, `"symmetric"` (not `"cipher"`).
22    pub name: &'static str,
23    /// Version of the wire protocol the plugin implements.
24    pub version: u8,
25}
26
27inventory::collect!(RegisteredInterface);
28
29/// Re-export of `inventory::submit!` under a `confium_api`-owned path so
30/// the `#[plugin_interface]` proc-macro can emit registrations through
31/// `$crate` without forcing every plugin crate to list `inventory` as a
32/// direct dependency. The `submit!` macro's internal `$crate`
33/// references still resolve to the `inventory` crate (macros are
34/// hygienic), so this re-export is sound.
35#[doc(hidden)]
36pub use inventory::submit as inventory_submit;
37
38/// Submit a [`RegisteredInterface`] to the link-time registry. Thin
39/// wrapper around `inventory::submit!` so the `#[plugin_interface]`
40/// proc-macro can emit registrations through `confium_api` without
41/// forcing every plugin crate to depend on `inventory` directly.
42#[macro_export]
43macro_rules! register_interface {
44    ($name:expr, $version:expr) => {
45        $crate::registry::inventory_submit! {
46            $crate::registry::RegisteredInterface {
47                name: $name,
48                version: $version,
49            }
50        }
51    };
52}
53
54/// Iterator over every interface registered in the linked plugin crate.
55/// Used by the `#[export]` macro to populate `cfmp_query_interfaces`
56/// without requiring the plugin author to redeclare the list.
57pub fn iter() -> impl Iterator<Item = &'static RegisteredInterface> {
58    inventory::iter::<RegisteredInterface>.into_iter()
59}