tree-builder-macro 0.0.1

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

pub fn option_invocation(term: &RegTerm) -> TokenStream2 {
    let term = if matches!(term, RegTerm::Metacharacter(_)) {
        term_invocation(term)
    } else {
        super::term::term(term)
    };
    quote! {tree_builder::__private::nom::combinator::opt(#term)}
}

pub fn option_post(term: &RegTerm) -> TokenStream2 {
    let (decl, unwrap) = match term {
        RegTerm::Ident(ident) => {
            let ident = format_ident!("{}", ident);
            (
                quote! {let #ident (res)},
                quote! {*res.unwrap_or_else(|| Box::new(#ident (String::new())))},
            )
        },
        RegTerm::Metacharacter(_) | RegTerm::Terminal(_) => {
            (
                quote! {let res},
                quote! {res.map(|x|x.to_owned()).unwrap_or_else(|| String::new())}
                )
        }
        _ => (
            quote! {let res},
            quote! {res.unwrap_or_else(||String::new())},
        ),
    };
    quote! {#decl = #unwrap ;}
}

pub fn many1(term: &RegTerm) -> TokenStream2 {
    let term_stream = super::term::term(term);
    if matches!(term, RegTerm::Metacharacter(_)) {
        quote! {tree_builder::__private::nom::bytes::complete::take_while1(#term_stream)}
    } else {
        quote! {tree_builder::__private::nom::multi::many1(#term_stream)}
    }
}

pub fn many0(term: &RegTerm) -> TokenStream2 {
    let term_stream = super::term::term(term);
    if matches!(term, RegTerm::Metacharacter(_)) {
        quote! {tree_builder::__private::nom::bytes::complete::take_while(#term_stream)}
    } else {
        quote! {tree_builder::__private::nom::multi::many0(#term_stream)}
    }
}

pub fn term_invocation(term: &RegTerm) -> TokenStream2 {
    let cond = super::term::term(term);

    match term {
        RegTerm::Metacharacter(_) => {
            quote! {tree_builder::public_parsers::satisfy_one(#cond)}
        }
        _ => cond,
    }
}