statum-macros 0.8.8

Proc macros for representing legal workflow and protocol states explicitly in Rust
Documentation
use syn::ItemImpl;

use crate::contracts::ValidatorContract;

use super::contract::{ValidatorPlan, build_variant_lookup};
use super::signatures::{
    ValidatorDiagnosticContext, build_validator_method_contract, validator_state_name_from_ident,
};

pub(super) fn collect_validator_plan(
    item_impl: &ItemImpl,
    contract: &ValidatorContract,
) -> Result<ValidatorPlan, proc_macro2::TokenStream> {
    let mut methods = Vec::new();
    let mut has_async = false;
    let (variant_specs, variant_by_name) = build_variant_lookup(&contract.state_enum.variants)?;

    for item in &item_impl.items {
        let syn::ImplItem::Fn(func) = item else {
            continue;
        };

        let Some(state_name) = validator_state_name_from_ident(&func.sig.ident) else {
            continue;
        };
        let Some(spec_idx) = variant_by_name.get(&state_name) else {
            continue;
        };
        let spec = &variant_specs[*spec_idx];
        let diagnostic_context = ValidatorDiagnosticContext {
            persisted_type_display: &contract.persisted_type_display,
            machine_name: &contract.resolved_machine.machine_name,
            state_enum_name: &contract.state_enum.name,
            variant_name: &spec.variant_name,
            machine_fields: &contract.resolved_machine.field_names,
            expected_ok_type: &spec.expected_ok_type,
        };
        let method_contract = build_validator_method_contract(func, spec, &diagnostic_context)?;

        if method_contract.is_async {
            has_async = true;
        }
        methods.push(method_contract);
    }

    Ok(ValidatorPlan { methods, has_async })
}