From 008a765fe3bccbec873e2c869cf7004e55bbaad7 Mon Sep 17 00:00:00 2001 From: Albin Chaboissier Date: Wed, 11 Mar 2026 21:49:02 +0100 Subject: [PATCH] Zyn --- Cargo.lock | 34 +++++- oxydsp-flowgraph-macros/Cargo.toml | 4 +- oxydsp-flowgraph-macros/src/lib.rs | 168 +++++++++++------------------ oxydsp-flowgraph/src/edge.rs | 6 +- 4 files changed, 100 insertions(+), 112 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0390bc8..0e56a4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,9 +17,7 @@ dependencies = [ name = "oxydsp-flowgraph-macros" version = "0.1.0" dependencies = [ - "proc-macro2", - "quote", - "syn", + "zyn", ] [[package]] @@ -56,3 +54,33 @@ name = "unicode-ident" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "zyn" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1821d8c02040d27b081b0e3552933622411b5fdd62d3529ee1e693e37084afe" +dependencies = [ + "zyn-core", + "zyn-derive", +] + +[[package]] +name = "zyn-core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718adc314c1f0745d0c54a38226285338a7b800848c49529e282ee41cdbcdb31" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zyn-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e592b35728519732b11b0b26d4c6feb9756dc1b805fc204a75c4348ef331ff3" +dependencies = [ + "zyn-core", +] diff --git a/oxydsp-flowgraph-macros/Cargo.toml b/oxydsp-flowgraph-macros/Cargo.toml index 3b618b7..dcc3f20 100644 --- a/oxydsp-flowgraph-macros/Cargo.toml +++ b/oxydsp-flowgraph-macros/Cargo.toml @@ -7,6 +7,4 @@ edition = "2024" proc-macro = true [dependencies] -proc-macro2 = "1.0.106" -quote = "1.0.45" -syn = "2.0.117" +zyn = {version = "0.4.2", features = ["ext"]} diff --git a/oxydsp-flowgraph-macros/src/lib.rs b/oxydsp-flowgraph-macros/src/lib.rs index 46ba18c..609fe1c 100644 --- a/oxydsp-flowgraph-macros/src/lib.rs +++ b/oxydsp-flowgraph-macros/src/lib.rs @@ -1,124 +1,84 @@ -use proc_macro::TokenStream; -use quote::quote; -use syn::{DeriveInput, Fields, Ident, parse_macro_input}; +use zyn::ext::AttrExt; +use zyn::ext::FieldsExt; -#[proc_macro_derive(BlockIO, attributes(input, output))] -pub fn derive_block_io(item: TokenStream) -> TokenStream +#[zyn::derive("BlockIO", attributes(input, output))] +pub fn block_io( + #[zyn(input)] ident: zyn::Extract, + #[zyn(input)] generics: zyn::Extract, + #[zyn(input)] fields: zyn::Fields, +) -> zyn::TokenStream { - let input = parse_macro_input!(item as DeriveInput); - let inputs; - let outputs; - match input.data - { - syn::Data::Struct(data_struct) => + let (impl_generics, type_generics, where_clause) = generics.split_for_impl(); + zyn::zyn!( + impl {{impl_generics}} oxydsp_flowgraph::block::BlockIO for {{ ident.inner() }} {{ type_generics }} + where {{ where_clause }} { - inputs = derive_block_get_marked_idents(&data_struct.fields, "input"); - outputs = derive_block_get_marked_idents(&data_struct.fields, "output"); + @block_io_set_index(fields = fields.clone()) + @block_io_get_successors(fields = fields.clone()) + @block_io_counts(fields = fields.clone()) } - syn::Data::Enum(_) | syn::Data::Union(_) => unimplemented!("Enum/Unions not supported"), - } - - let struct_name = input.ident; - let func_set_index = derive_block_set_index(&inputs, &outputs); - let func_get_successors = derive_block_get_successors(&outputs); - let (impl_generics, type_generics, where_clause) = input.generics.split_for_impl(); - - quote! { - impl #impl_generics oxydsp_flowgraph::block::BlockIO for #struct_name #type_generics - #where_clause - { - #func_set_index - - #func_get_successors - } - } - .into() + ) } -fn derive_block_get_successors(outputs: &Vec) -> proc_macro2::TokenStream +#[zyn::element] +fn block_io_set_index(fields: zyn::syn::Fields) -> zyn::TokenStream { - quote! { - fn get_successors(&self) -> Vec + let fields = fields.as_named().unwrap().named.clone(); + zyn::zyn!( + fn set_index(&self, block_index: usize) { - let mut successors = Vec::new(); - #( - if let Some(next) = self.#outputs.get_consumer_block() - { - successors.push(next); - } - )* - successors + use oxydsp_flowgraph::edge::BlockIOIndex; + @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("input"))).enumerate()) + { + self.{{field.1.ident}}.set_block_index(BlockIOIndex {block_index, port_index: {{ field.0 }} }); + } + + @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate()) + { + self.{{field.1.ident}}.set_block_index(BlockIOIndex {block_index, port_index: {{ field.0 }} }); + } } - } + ) } -fn derive_block_io_count(inputs: &Vec, outputs: &Vec) -> proc_macro2::TokenStream +#[zyn::element] +fn block_io_get_successors(fields: zyn::syn::Fields) -> zyn::TokenStream { - let input_count = inputs.len(); - let output_count = outputs.len(); - quote! { + let fields = fields.as_named().unwrap().named.clone(); + zyn::zyn!( + fn get_successors(&self, block_index: usize) -> Vec + { + let mut output = vec![]; + @for (field in fields.iter().filter(|x| x.attrs.iter().any(|x| x.is("output"))).enumerate()) + { + output.push(self.{{ field.1.ident }}.get_consumer_block()); + } + output + } + ) +} + +#[zyn::element] +fn block_io_counts(fields: zyn::syn::Fields) -> zyn::TokenStream +{ + let fields = fields.as_named().unwrap().named.clone(); + let input_count = fields + .iter() + .filter(|x| x.attrs.iter().any(|x| x.is("input"))) + .count(); + let output_count = fields + .iter() + .filter(|x| x.attrs.iter().any(|x| x.is("output"))) + .count(); + zyn::zyn!( fn input_count(&self) -> usize { - #input_count + return { { input_count } }; } fn output_count(&self) -> usize { - #output_count + return { { output_count } }; } - } -} - -fn derive_block_set_index(inputs: &Vec, outputs: &Vec) -> proc_macro2::TokenStream -{ - quote! { - fn set_index(&self, block_index: usize) - { - use oxydsp_flowgraph::edge::BlockIOIndex; - let mut counter = 0; - #( - self.#inputs.set_block_index( - BlockIOIndex - { - block_index, - port_index: counter, - } - ); - counter += 1; - )* - counter = 0; - #( - self.#outputs.set_block_index( - BlockIOIndex - { - block_index, - port_index: counter, - } - ); - counter += 1; - )* - } - } -} - -fn derive_block_get_marked_idents>( - fields: &Fields, - required_attribute: S, -) -> Vec -{ - let mut idents = vec![]; - for field in fields - { - 'inner: for attribute in field.attrs.iter() - { - if let Some(name) = attribute.meta.path().segments.first() - && name.ident == required_attribute.as_ref() - { - idents.push(field.ident.clone().unwrap()); - break 'inner; - } - } - } - - idents + ) } diff --git a/oxydsp-flowgraph/src/edge.rs b/oxydsp-flowgraph/src/edge.rs index 19d0139..14d6b15 100644 --- a/oxydsp-flowgraph/src/edge.rs +++ b/oxydsp-flowgraph/src/edge.rs @@ -1,6 +1,8 @@ -use std::sync::{Arc, Mutex}; +use std::sync::Arc; +use std::sync::Mutex; -use crate::stream::{StreamConsumer, StreamProducer}; +use crate::stream::StreamConsumer; +use crate::stream::StreamProducer; pub struct Edge {