Initial commit
This commit is contained in:
1
ntw_flowgraph_macros/.gitignore
vendored
Normal file
1
ntw_flowgraph_macros/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
||||
47
ntw_flowgraph_macros/Cargo.lock
generated
Normal file
47
ntw_flowgraph_macros/Cargo.lock
generated
Normal file
@ -0,0 +1,47 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "streams_macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
12
ntw_flowgraph_macros/Cargo.toml
Normal file
12
ntw_flowgraph_macros/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "ntw_flowgraph_macros"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0.106"
|
||||
quote = "1.0.45"
|
||||
syn = {version = "2.0.117", features = ["extra-traits"]}
|
||||
126
ntw_flowgraph_macros/src/lib.rs
Normal file
126
ntw_flowgraph_macros/src/lib.rs
Normal file
@ -0,0 +1,126 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::DeriveInput;
|
||||
use syn::Ident;
|
||||
use syn::parse_macro_input;
|
||||
|
||||
struct BlockDerive
|
||||
{
|
||||
input_fields: Vec<Ident>,
|
||||
output_fields: Vec<Ident>,
|
||||
}
|
||||
|
||||
fn set_block_index_func(ctx: &BlockDerive) -> proc_macro2::TokenStream
|
||||
{
|
||||
let inputs = ctx.input_fields.clone();
|
||||
quote! {
|
||||
fn set_block_index(&self, index: usize)
|
||||
{
|
||||
#({
|
||||
self.#inputs.set_index(index);
|
||||
})*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_successors_func(ctx: &BlockDerive) -> proc_macro2::TokenStream
|
||||
{
|
||||
let outputs = ctx.output_fields.clone();
|
||||
quote! {
|
||||
fn get_successors(&self) -> Vec<usize>
|
||||
{
|
||||
let mut output = vec![];
|
||||
#(
|
||||
match self.#outputs.get_successor()
|
||||
{
|
||||
None => {},
|
||||
Some(x) => output.push(x)
|
||||
}
|
||||
)*
|
||||
|
||||
output
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[proc_macro_derive(Block, attributes(input, output))]
|
||||
pub fn block_derive(item: TokenStream) -> TokenStream
|
||||
{
|
||||
let cloned = item.clone();
|
||||
let input = parse_macro_input!(cloned as DeriveInput);
|
||||
|
||||
let data_struct = match input.data
|
||||
{
|
||||
syn::Data::Struct(data_struct) => data_struct,
|
||||
syn::Data::Enum(_) | syn::Data::Union(_) => panic!(),
|
||||
};
|
||||
|
||||
let struct_fields = match data_struct.fields
|
||||
{
|
||||
syn::Fields::Named(fields_named) => fields_named,
|
||||
syn::Fields::Unnamed(_) | syn::Fields::Unit => panic!(),
|
||||
};
|
||||
|
||||
let input_fields = struct_fields
|
||||
.named
|
||||
.iter()
|
||||
.filter_map(|f| {
|
||||
if f.ident.is_some()
|
||||
&& f.attrs.iter().any(|attr| {
|
||||
attr.meta
|
||||
.path()
|
||||
.segments
|
||||
.last()
|
||||
.is_some_and(|s| s.ident == "input")
|
||||
})
|
||||
{
|
||||
Some(f.ident.clone().unwrap())
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let output_fields = struct_fields
|
||||
.named
|
||||
.iter()
|
||||
.filter_map(|f| {
|
||||
if f.ident.is_some()
|
||||
&& f.attrs.iter().any(|attr| {
|
||||
attr.meta
|
||||
.path()
|
||||
.segments
|
||||
.last()
|
||||
.is_some_and(|s| s.ident == "output")
|
||||
})
|
||||
{
|
||||
Some(f.ident.clone().unwrap())
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let derive = BlockDerive {
|
||||
input_fields,
|
||||
output_fields,
|
||||
};
|
||||
|
||||
let set_index_func = set_block_index_func(&derive);
|
||||
let get_successors_func = get_successors_func(&derive);
|
||||
let struct_path = input.ident;
|
||||
|
||||
//item
|
||||
quote! {
|
||||
impl Block for #struct_path
|
||||
{
|
||||
#set_index_func
|
||||
#get_successors_func
|
||||
}
|
||||
}
|
||||
.into()
|
||||
}
|
||||
Reference in New Issue
Block a user