workshop-rs 1.4.3

Canonical multi-locale Overwatch Workshop semantic core: catalog, parser, WIR, validation, emitter.
Documentation
//! Complete-program canonical validation orchestrated by the Workshop rule
//! domain.

use crate::catalog::Catalog;
use crate::core::error::Result;
use crate::wir;

/// Validate every builtin reference in a Workshop-origin WIR program against
/// the canonical catalog: action/value call names must be known canonical ids,
/// and event/enum references must resolve to canonical identities.
///
/// Calls must supply every declared parameter that carries no catalog default;
/// a trailing parameter with a declared default (for example `Wait`'s
/// `waitBehavior`) is optional and may be omitted. Variable names are bound at
/// parse time: an undeclared name allocates an implicit variable slot rather
/// than failing validation.
pub fn validate_canonical_ids(program: &crate::Program, catalog: &Catalog) -> Result<()> {
    let storage = program.to_wir()?;
    validate_wir(&storage, catalog)
}

#[cfg(test)]
pub(crate) fn validate_canonical_ids_wir(program: &wir::Program, catalog: &Catalog) -> Result<()> {
    validate_wir(program, catalog)
}

pub(crate) fn validate_wir(program: &wir::Program, catalog: &Catalog) -> Result<()> {
    for (index, _) in program.rules.iter().enumerate() {
        let rule = wir::RuleId::from_index(index);
        let Some(rule_data) = program.rules.get(rule) else {
            continue;
        };
        crate::events::validate::validate_event(&rule_data.event, rule_data.span, catalog)?;
        for action in &rule_data.actions {
            crate::actions::validate::validate_action(program, catalog, *action)?;
        }
        for condition in &rule_data.conditions {
            crate::values::validate::validate_value(program, catalog, condition.value)?;
        }
    }
    Ok(())
}