1pub use daedalus_macros::node;
6pub type NodeDescriptor = daedalus_registry::store::NodeDescriptor;
7
8#[cfg(feature = "bundle-starter")]
9mod bundle_starter;
10
11#[cfg(feature = "bundle-utils")]
12mod bundle_utils;
13
14#[cfg(feature = "registry-adapter")]
15pub mod registry_adapter;
16
17#[cfg(feature = "planner-adapter")]
18pub mod planner_adapter;
19
20pub mod bundle_demo;
21extern crate self as daedalus_nodes;
22pub mod __macro_support {
23 pub use daedalus_runtime::plugins::{NodeInstall, Plugin, PluginRegistry};
24}
25
26#[macro_export]
42macro_rules! declare_plugin {
43 ($plugin:ident, $id:expr, [ $( $node:ident ),+ $(,)? ]) => {
45 paste::paste! {
46 #[derive(Clone, Debug)]
47 pub struct $plugin {
48 $(pub $node: [<$node Handle>]),+
49 }
50
51 impl $plugin {
52 pub fn new() -> Self {
53 Self {
54 $($node: $node::handle().with_prefix($id)),+
55 }
56 }
57
58 $(
59 pub fn [<node_ $node>](&self) -> [<$node Handle>] {
60 $node::handle().with_prefix($id)
61 }
62 )+
63 }
64
65 impl Default for $plugin {
66 fn default() -> Self {
67 Self::new()
68 }
69 }
70
71 impl $plugin {
72 pub fn install(
73 &self,
74 registry: &mut $crate::__macro_support::PluginRegistry,
75 ) -> Result<(), &'static str> {
76 $(
77 registry.merge::<$node>()?;
78 )+
79 Ok(())
80 }
81 }
82
83 #[cfg(feature = "plugins")]
84 impl $crate::__macro_support::Plugin for $plugin {
85 fn id(&self) -> &'static str {
86 $id
87 }
88
89 fn install(
90 &self,
91 registry: &mut $crate::__macro_support::PluginRegistry,
92 ) -> Result<(), &'static str> {
93 self.install(registry)
94 }
95 }
96 }
97 };
98
99 ($plugin:ident, $id:expr, [ $( $node:ident ),+ $(,)? ], install = |$reg:ident| $body:block) => {
102 paste::paste! {
103 #[derive(Clone, Debug)]
104 pub struct $plugin {
105 $(pub $node: [<$node Handle>]),+
106 }
107
108 impl $plugin {
109 pub fn new() -> Self {
110 Self {
111 $($node: $node::handle().with_prefix($id)),+
112 }
113 }
114
115 $(
116 pub fn [<node_ $node>](&self) -> [<$node Handle>] {
117 $node::handle().with_prefix($id)
118 }
119 )+
120 }
121
122 impl Default for $plugin {
123 fn default() -> Self {
124 Self::new()
125 }
126 }
127
128 impl $plugin {
129 pub fn install(
130 &self,
131 registry: &mut $crate::__macro_support::PluginRegistry,
132 ) -> Result<(), &'static str> {
133 let $reg = registry;
134 (|| -> Result<(), &'static str> { $body; Ok(()) })()?;
135 $(
136 $reg.merge::<$node>()?;
137 )+
138 Ok(())
139 }
140 }
141
142 #[cfg(feature = "plugins")]
143 impl $crate::__macro_support::Plugin for $plugin {
144 fn id(&self) -> &'static str {
145 $id
146 }
147
148 fn install(
149 &self,
150 registry: &mut $crate::__macro_support::PluginRegistry,
151 ) -> Result<(), &'static str> {
152 self.install(registry)
153 }
154 }
155 }
156 };
157}
158
159pub fn register_all() -> Vec<NodeDescriptor> {
167 let mut nodes: Vec<NodeDescriptor> = Vec::new();
168 #[cfg(feature = "bundle-starter")]
169 {
170 nodes.extend(bundle_starter::nodes());
171 }
172 #[cfg(feature = "bundle-utils")]
173 {
174 nodes.extend(bundle_utils::nodes());
175 }
176 nodes.sort_by(|a, b| a.id.0.cmp(&b.id.0));
177 nodes
178}
179
180#[cfg(all(test, feature = "bundle-starter"))]
181mod tests {
182 use super::*;
183 use daedalus_core::compute::ComputeAffinity;
184
185 #[test]
186 fn deterministic_ordering() {
187 let nodes = register_all();
188 let mut sorted = nodes.clone();
189 sorted.sort_by(|a, b| a.id.0.cmp(&b.id.0));
190 assert_eq!(nodes, sorted);
191 }
192
193 #[test]
194 fn node_macro_attaches_metadata() {
195 let first = register_all()
196 .into_iter()
197 .find(|n| n.id.0 == "starter.print")
198 .expect("starter.print registered");
199 assert_eq!(first.default_compute, ComputeAffinity::CpuOnly);
200 }
201}