Expand description
polydat-derive — proc-macro implementation of
#[polydat_node].
See docs/SRD/80_node_function_macro_collapse.md
for the design, the 8 open design questions this proc-macro
is closing one-at-a-time, and the migration plan against
existing polydat library nodes.
§Current scope (PR B.1)
This is the SCAFFOLDING pass. The macro recognizes the simplest case only:
- A standalone
fn(noimplblock, no struct). - All wire input arguments are PRIMITIVES with implementations
of polydat’s
FromValuetrait — concretely:u64,f64,bool,&str(or ownedString). - Return type is a PRIMITIVE with a
IntoValueimplementation — same set. - No state, no const args, no JIT hooks, no variadic shapes, no polymorphism.
Out of scope (deferred to later PR B.* batches):
- State-bearing nodes (probability PRNG, vectors readers).
- JIT-eligible nodes (the
compiled_u64hooks). - Const-arg parameters with
ConstConstraint. - Variadic shapes (
Variadic<T>,&[T]). - Polymorphic outputs (
SameAsInput). - Ext-typed args / returns (adapter-contributed types).
§Generated output (for the simple case)
Input:
#[polydat_node]
fn str_eq(a: &str, b: &str) -> u64 {
if a == b { 1 } else { 0 }
}Generated:
pub struct StrEq { meta: polydat::ast::NodeMeta }
impl Default for StrEq { fn default() -> Self { Self::new() } }
impl StrEq {
pub fn new() -> Self {
Self {
meta: polydat::ast::NodeMeta {
name: "str_eq".into(),
ins: vec![
polydat::ast::Slot::Wire(polydat::ast::Port::new(
"a", polydat::ast::PortType::Str)),
polydat::ast::Slot::Wire(polydat::ast::Port::new(
"b", polydat::ast::PortType::Str)),
],
outs: vec![polydat::ast::Port::new(
"output", polydat::ast::PortType::U64)],
},
}
}
}
impl polydat::ast::PolydatNode for StrEq {
fn meta(&self) -> &polydat::ast::NodeMeta { &self.meta }
fn eval(
&self,
inputs: &[polydat::ast::Value],
outputs: &mut [polydat::ast::Value],
) {
let a = <&str as polydat::derive_support::FromValue>::from_value(&inputs[0]);
let b = <&str as polydat::derive_support::FromValue>::from_value(&inputs[1]);
let result: u64 = if a == b { 1 } else { 0 };
outputs[0] = <u64 as polydat::derive_support::IntoValue>::into_value(result);
}
}The original fn str_eq is consumed by the macro — only the
struct + impl is emitted. The body of str_eq becomes the
body of the eval method (with parameter rebinding via
FromValue::from_value).
FuncSig registration via inventory or similar is deferred to PR B.2 — for now the macro just generates the struct + impl so we can validate the boxing/unboxing path with a pilot node.
Attribute Macros§
- polydat_
node #[polydat_node]— derive a polydat node from a typed Rust function signature.