Skip to main content

khive_runtime/
pack_metadata.rs

1//! Generate object-safe pack metadata accessors from the pack's associated constants.
2//!
3//! Use [`crate::pack_runtime_metadata!`] inside a `PackRuntime` implementation and
4//! [`crate::pack_factory_metadata!`] inside its factory implementation. Dispatch,
5//! construction, lifecycle hooks, input schemas and validation rule implementations
6//! remain explicit; their behavior cannot be derived from metadata constants.
7
8// Macro expansions use this re-export so consumers need no particular import
9// spelling or direct dependency on khive-types.
10#[doc(hidden)]
11pub use khive_types::Pack;
12
13/// Delegate every const-backed `PackRuntime` metadata accessor to `Self: Pack`.
14///
15/// Invoke once inside `impl PackRuntime for MyPack` as
16/// `khive_runtime::pack_runtime_metadata!();`. It emits `name`, `note_kinds`,
17/// `entity_kinds`, `brain_consumer_kinds`, `handlers`, `edge_rules`, `entity_types`,
18/// `requires`, `note_kind_specs`, `note_embedding_policies`, `schema_plan` and
19/// `schema_column_additions`. Do not also implement those methods manually.
20///
21/// A missing `Pack::SCHEMA_PLAN` becomes `SchemaPlan::empty()`. Validation rule
22/// values remain explicit because `Pack::VALIDATION_RULES` contains only ids.
23#[macro_export]
24macro_rules! pack_runtime_metadata {
25    () => {
26        fn name(&self) -> &str {
27            <Self as $crate::pack_metadata::Pack>::NAME
28        }
29
30        fn note_kinds(&self) -> &'static [&'static str] {
31            <Self as $crate::pack_metadata::Pack>::NOTE_KINDS
32        }
33
34        fn entity_kinds(&self) -> &'static [&'static str] {
35            <Self as $crate::pack_metadata::Pack>::ENTITY_KINDS
36        }
37
38        fn brain_consumer_kinds(&self) -> &'static [&'static str] {
39            <Self as $crate::pack_metadata::Pack>::BRAIN_CONSUMER_KINDS
40        }
41
42        fn handlers(&self) -> &'static [$crate::pack::HandlerDef] {
43            <Self as $crate::pack_metadata::Pack>::HANDLERS
44        }
45
46        fn edge_rules(&self) -> &'static [$crate::pack::EdgeEndpointRule] {
47            <Self as $crate::pack_metadata::Pack>::EDGE_RULES
48        }
49
50        fn entity_types(&self) -> &'static [$crate::pack::EntityTypeDef] {
51            <Self as $crate::pack_metadata::Pack>::ENTITY_TYPES
52        }
53
54        fn requires(&self) -> &'static [&'static str] {
55            <Self as $crate::pack_metadata::Pack>::REQUIRES
56        }
57
58        fn note_kind_specs(&self) -> &'static [$crate::pack::NoteKindSpec] {
59            <Self as $crate::pack_metadata::Pack>::NOTE_KIND_SPECS
60        }
61
62        fn note_embedding_policies(&self) -> &'static [$crate::pack::NoteEmbeddingPolicySpec] {
63            <Self as $crate::pack_metadata::Pack>::NOTE_EMBEDDING_POLICIES
64        }
65
66        fn schema_column_additions(&self) -> &'static [$crate::pack::PackColumnAddition] {
67            <Self as $crate::pack_metadata::Pack>::SCHEMA_COLUMN_ADDITIONS
68        }
69
70        fn schema_plan(&self) -> $crate::SchemaPlan {
71            match <Self as $crate::pack_metadata::Pack>::SCHEMA_PLAN {
72                ::core::option::Option::Some(plan) => $crate::SchemaPlan {
73                    pack: plan.pack,
74                    statements: plan.statements,
75                },
76                ::core::option::Option::None => $crate::SchemaPlan::empty(),
77            }
78        }
79    };
80}
81
82/// Delegate a factory's name and dependencies to the pack type it constructs.
83///
84/// Invoke inside `impl PackFactory for MyFactory` as
85/// `khive_runtime::pack_factory_metadata!(MyPack);`. Construction, resolver,
86/// installation and intentionally-verbless behavior remain explicit.
87#[macro_export]
88macro_rules! pack_factory_metadata {
89    ($pack:ty) => {
90        fn name(&self) -> &'static str {
91            <$pack as $crate::pack_metadata::Pack>::NAME
92        }
93
94        fn requires(&self) -> &'static [&'static str] {
95            <$pack as $crate::pack_metadata::Pack>::REQUIRES
96        }
97    };
98}