tree-builder-macro 0.0.1

Macros for the tree-builder crate.
Documentation
use crate::parser::parser_ast::{RegConcatenation, RegFactor, RegTerm};
use proc_macro2::TokenStream as TokenStream2;
use quote::{format_ident, quote};

pub fn concatenation(RegConcatenation(concs): &RegConcatenation) -> TokenStream2 {
    let declaration = quote! {let (input, res) = };
    let mapper = |factor: &RegFactor| match factor {
        RegFactor::Term(term) => {
            let push = if matches!(term, RegTerm::Grouping(_) | RegTerm::Ident(_)) {
                super::owned_push()
            } else {
                super::standard_push()
            };
            let post = match term {
                RegTerm::Ident(name) => {
                    let ident = format_ident!("{}", name);
                    quote! {let #ident (res) = *res;}
                }
                _ => quote! {},
            };
            let invocation = super::factor::term_invocation(term);
            quote! {
                #declaration #invocation(input)?;
                #post
                #push
            }
        }
        RegFactor::Optional(term) => {
            let invocation = super::factor::option_invocation(term);
            let post = super::factor::option_post(term);
            let push = super::owned_push();
            quote! {
                #declaration #invocation(input)?;
                #post
                #push
            }
        }
        RegFactor::ZeroOrMore(term) => {
            let invocation = super::factor::many0(term);
            let (push, post) = match term {
                RegTerm::Ident(typ) => {
                    let ident = format_ident!("{}", typ);
                    (
                        super::owned_push(),
                        quote! {
                           let res: std::vec::Vec<std::string::String> = res.into_iter().map(|inp| {let inp = *inp; let #ident (inp) = inp; inp}).collect();
                           let res = res.join("");
                        },
                    )
                }
                RegTerm::Terminal(_) | RegTerm::Grouping(_) => {
                    (super::owned_push(), quote! {let res = res.join("");})
                }
                _ => (super::standard_push(), quote! {}),
            };
            quote! {
                #declaration #invocation(input)?;
                #post
                #push
            }
        }
        RegFactor::OneOrMore(term) => {
            let invocation = super::factor::many1(term);
            let (push, post) = match term {
                RegTerm::Ident(typ) => {
                    let ident = format_ident!("{}", typ);
                    (
                        super::owned_push(),
                        quote! {
                           let res: std::vec::Vec<std::string::String> = res.into_iter().map(|inp| {let inp = *inp; let #ident (inp) = inp; inp}).collect();
                           let res = res.join("");
                        },
                    )
                }
                RegTerm::Terminal(_) | RegTerm::Grouping(_) => {
                    (super::owned_push(), quote! {let res = res.join("");})
                }
                _ => (super::standard_push(), quote! {}),
            };
            quote! {
                #declaration #invocation(input)?;
                #post
                #push
            }
        }
    };
    let concs: Vec<TokenStream2> = concs.into_iter().map(mapper).collect();
    quote! {
        #(#concs)
        *
    }
}