use proc_macro::TokenStream;
use quote::{format_ident, quote};
use syn::{
parse::{Parse, ParseStream},
DeriveInput,
};
pub(crate) fn node(args: TokenStream, input: TokenStream) -> TokenStream {
let _args = syn::parse_macro_input!(args as NodeConfig);
let mut input = syn::parse_macro_input!(input as DeriveInput);
let vis = input.vis.clone();
let generics = input.generics.clone();
let node_name = input.ident.clone();
let node_name_str = node_name.to_string();
let data_name = format_ident!("{}{}", node_name, "Data");
input.ident = data_name.clone();
let mut impl_generics = generics.clone();
let lt = crate::first_lifetime(&mut impl_generics);
let mut output = proc_macro2::TokenStream::new();
output.extend(quote! {
#[moore_derive::arena]
#[moore_derive::walk_visitor(node)]
#vis type #node_name #impl_generics = Node<#lt, #data_name #generics>;
});
output.extend(quote! {
#[derive(
moore_derive::AcceptVisitorAndForeach,
moore_derive::AnyNodeData
)]
#input
});
crate::all_node::add_node(&node_name, &impl_generics);
output.extend(quote! {
impl #impl_generics BasicNode<#lt> for #node_name #impl_generics {
fn type_name(&self) -> &'static str {
#node_name_str
}
fn as_all(&#lt self) -> AllNode<#lt> {
AllNode::from(self)
}
fn as_any(&#lt self) -> &#lt AnyNode<#lt> {
self
}
}
});
output.into()
}
struct NodeConfig {}
impl Parse for NodeConfig {
fn parse(_input: ParseStream) -> syn::Result<Self> {
Ok(NodeConfig {})
}
}