sark-gen 0.29.0

Sark proc-macro generators
Documentation
use crate::{app::serve::handle::decode::arms, macros::tokens::local, runtime::paths::Paths};

pub(super) struct Flow<'a> {
    pub(super) prepared: &'a syn::Ident,
    pub(super) state: &'a syn::Ident,
    pub(super) family: &'a syn::Ident,
    pub(super) maps: &'a [proc_macro2::TokenStream],
    pub(super) each: &'a [proc_macro2::TokenStream],
    pub(super) folds: &'a [proc_macro2::TokenStream],
    pub(super) bodies: &'a [proc_macro2::TokenStream],
    pub(super) finish: &'a [proc_macro2::TokenStream],
    pub(super) open: &'a arms::Arms,
}

impl Flow<'_> {
    pub(super) fn render(&self, paths: &Paths) -> proc_macro2::TokenStream {
        use quote::quote;

        let ns_core = &paths.core;
        let [v_each, v_map, v_fold, v_visit] = ["each", "map", "fold", "visit"].map(local);

        let Self {
            prepared,
            state,
            family,
            maps,
            each,
            folds,
            bodies,
            finish,
            open,
        } = self;
        let open = open.render(paths, prepared);
        quote! {
            impl<F: #ns_core::decode::state::Set>
                #ns_core::decode::state::Flow<#prepared, F> for #state<F>
            {
                type Family = #family;

                fn each<'a, M: #ns_core::decode::state::Each<#prepared, F>>(
                    &'a mut self,
                    #v_each: M,
                ) -> M::Output<'a> { match self { #( #each )* } }

                fn map_retain<
                    G: #ns_core::decode::state::Set,
                    M: #ns_core::decode::state::Map<#prepared, F, G>,
                >(self, #v_map: M) ->
                    ::core::ops::ControlFlow<M::Break, (M::Retained, #state<G>)>
                { match self { #( #maps )* } }

                fn fold<T: #ns_core::decode::state::Fold<#prepared, F>>(
                    self,
                    #v_fold: T,
                ) -> T::Output { match self { #( #folds )* } }

                fn finish(self) -> ::core::result::Result<Self, Self>
                where F: #ns_core::decode::state::Finish,
                { match self { #( #finish )* } }

                #open
            }

            impl<F: #ns_core::decode::state::Set>
                #ns_core::decode::state::body::Flow<F> for #state<F>
            {
                fn fold<V: #ns_core::decode::state::body::Fold<F>>(
                    self,
                    #v_visit: V,
                ) -> V::Output { match self { #( #bodies )* } }
            }
        }
    }
}