sark-gen 0.29.3

Sark proc-macro generators
Documentation
use crate::{macros::tokens::local, runtime::paths::Paths};

pub(super) struct Arms {
    borrow: Vec<proc_macro2::TokenStream>,
    take: Vec<proc_macro2::TokenStream>,
    consume: Vec<proc_macro2::TokenStream>,
}

impl Arms {
    pub(super) fn new() -> Self {
        Self {
            borrow: Vec::new(),
            take: Vec::new(),
            consume: Vec::new(),
        }
    }

    pub(super) fn push_active(
        &mut self,
        action: &syn::Ident,
        open: &syn::Ident,
        done: &syn::Ident,
    ) {
        use quote::quote;

        let [v_body, v_never, v_slot, v_visit] = ["body", "never", "slot", "visit"].map(local);
        let borrow = quote! {
            Self::#open(.., #v_body) => #v_visit.apply(#v_body),
            Self::#done(.., #v_never) => match *#v_never {},
        };
        let take = quote! {
            Self::#open(#v_slot, #v_body) => #v_visit.#action(#v_slot, #v_body),
            Self::#done(.., #v_never) => match #v_never {},
        };
        let consume = quote! {
            Self::#open(.., #v_body) => #v_visit(#v_body),
            Self::#done(.., #v_never) => match #v_never {},
        };
        self.borrow.push(borrow);
        self.take.push(take);
        self.consume.push(consume);
    }

    pub(super) fn push_never(&mut self, open: &syn::Ident, done: &syn::Ident) {
        use quote::quote;

        let v_never = local("never");

        self.borrow.push(quote! {
            Self::#open(.., #v_never) => match *#v_never {},
            Self::#done(.., #v_never) => match *#v_never {},
        });
        let arms = quote! {
            Self::#open(.., #v_never) => match #v_never {},
            Self::#done(.., #v_never) => match #v_never {},
        };
        self.take.push(arms.clone());
        self.consume.push(arms);
    }

    pub(super) fn render(&self, paths: &Paths, prep: &syn::Ident) -> proc_macro2::TokenStream {
        use quote::quote;

        let ns_core = &paths.core;
        let v_visit = local("visit");

        let Self {
            borrow,
            take,
            consume,
        } = self;
        quote! {
                fn each_open<'a, V: #ns_core::decode::state::open::Each<F>>(
                    &'a mut self,
                    #v_visit: V,
                ) -> V::Output<'a>
                where F: #ns_core::decode::state::open::Set,
                { match self { #( #borrow )* } }

                fn fold_open<V: #ns_core::decode::state::open::Fold<#prep, F>>(
                    self,
                    #v_visit: V,
                ) -> V::Output
                where F: #ns_core::decode::state::open::Set,
                { match self { #( #take )* } }

                fn consume<O, V: ::core::ops::FnOnce(F::Body) -> O>(
                    self,
                    #v_visit: V,
                ) -> O
                where F: #ns_core::decode::state::open::Set,
                { match self { #( #consume )* } }
        }
    }
}