etdl-compiler 0.2.0

ETDL compiler: IEC 61025 fault tree resolution, MOCUS cut sets, ECEL type-checking, semantic validation, and code generation for event-driven microservices
Documentation
//! Generated-code compile check.
//!
//! Generates Rust for the order-fulfillment fixture, writes it into the
//! `etdl-gencheck` crate's `src/generated.rs`, and runs
//! `cargo check --features gen-check` to prove the generated code compiles
//! against the etdl-core runtime and the message/handler stubs.
//!
//! This is the primary guard against generated-code regressions (P0-1).

use std::path::PathBuf;
use std::process::Command;

const FIXTURE: &str = "order-fulfillment.etdl";

fn manifest_dir() -> PathBuf {
    PathBuf::from(env!("CARGO_MANIFEST_DIR"))
}

fn fixture_path() -> PathBuf {
    let cli_dir = manifest_dir().join("../etdl-cli");
    cli_dir.join("tests").join("fixtures").join(FIXTURE)
}

fn fixture_base() -> PathBuf {
    let cli_dir = manifest_dir().join("../etdl-cli");
    cli_dir.join("tests").join("fixtures")
}

fn gencheck_src() -> PathBuf {
    manifest_dir().join("tests").join("gencheck").join("src")
}

#[test]
fn generated_code_compiles() {
    let doc = etdl_parser::parse_document_from_file(&fixture_path()).expect("fixture parses");
    let registry =
        etdl_parser::load_asyncapi_imports(&doc, &fixture_base()).expect("asyncapi imports load");
    let result = etdl_compiler::Compiler::new().compile(&doc, &registry);

    let errors: Vec<_> = result.diagnostics.iter().filter(|d| d.is_error()).collect();
    assert!(
        errors.is_empty(),
        "fixture should have no errors, got {:?}",
        errors
    );

    let generated = result.rust_output.expect("compile produced output");

    // Write the generated file into the gencheck crate's src/ directory.
    let out_path = gencheck_src().join("generated.rs");
    std::fs::write(&out_path, &generated).expect("write generated code");

    // Run `cargo check --features gen-check` on the gencheck crate.
    let status = Command::new("cargo")
        .args(["check", "--quiet", "--features", "gen-check"])
        .current_dir(gencheck_src().parent().unwrap())
        .status()
        .expect("cargo check runs");

    // Clean up the generated artifact so the workspace stays pristine.
    let _ = std::fs::remove_file(&out_path);

    assert!(
        status.success(),
        "generated code failed `cargo check`. Dump:\n{}",
        generated
    );
}