statum-macros 0.9.0

Proc macros for representing legal workflow and protocol states explicitly in Rust
Documentation
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Generics, Ident, Visibility};

use crate::state::{ParsedVariantInfo, ParsedVariantShape};

pub(in crate::machine::emission) struct BuilderContext<'a> {
    pub(in crate::machine::emission) machine_ident: &'a Ident,
    pub(in crate::machine::emission) machine_generics: &'a Generics,
    pub(in crate::machine::emission) builder_vis: &'a Visibility,
    pub(in crate::machine::emission) field_names: &'a [Ident],
    pub(in crate::machine::emission) field_types: &'a [syn::Type],
    pub(in crate::machine::emission) use_ra_shim: bool,
}

pub(in crate::machine::emission) fn variant_payload_type(
    variant: &ParsedVariantInfo,
) -> Option<syn::Type> {
    match &variant.shape {
        ParsedVariantShape::Unit => None,
        ParsedVariantShape::Tuple { data_type } => Some(*data_type.clone()),
        ParsedVariantShape::Named {
            data_struct_ident, ..
        } => Some(syn::parse_quote!(#data_struct_ident)),
    }
}

pub(in crate::machine::emission) fn machine_struct_initialization(
    context: &BuilderContext<'_>,
    has_state_data: bool,
) -> TokenStream {
    let machine_ident = context.machine_ident;
    let field_names = context.field_names;
    let state_data = if has_state_data {
        quote! { state_data }
    } else {
        quote! { state_data: () }
    };

    if !field_names.is_empty() {
        quote! {
            #machine_ident {
                marker: core::marker::PhantomData,
                #state_data,
                #(#field_names,)*
            }
        }
    } else {
        quote! {
            #machine_ident {
                marker: core::marker::PhantomData,
                #state_data,
            }
        }
    }
}