vyre-conform 0.1.0

Conformance suite for vyre backends — proves byte-identical output to CPU reference
Documentation
//! Category B Round 2: `enum_dispatch` must **not** be treated as a Category B violation.

mod support;

use std::fs;
use std::sync::atomic::{AtomicU64, Ordering};

use vyre_conform::enforce::category::check_category_b_tripwire;

static COUNTER: AtomicU64 = AtomicU64::new(0);

fn temp_vyre_root() -> support::TempDir {
    let p = std::env::temp_dir().join(format!(
        "vyre-conform-catb-r2-enum-dispatch-{}-{}",
        std::process::id(),
        COUNTER.fetch_add(1, Ordering::SeqCst)
    ));
    fs::create_dir_all(p.join("runtime")).expect("mkdir runtime");
    support::TempDir { path: p }
}

#[test]
fn enum_dispatch_attribute_does_not_false_positive() {
    let root = temp_vyre_root();
    let source = r#"#[enum_dispatch::enum_dispatch]
pub trait Plugin {
    fn id(&self) -> u32;
}

pub enum Plugins {
    A(u32),
}

impl Plugin for Plugins {
    fn id(&self) -> u32 {
        0
    }
}
"#;
    let path = root.join("runtime").join("enum_dispatch_fixture.rs");
    fs::write(&path, source).expect("write fixture");

    let findings = check_category_b_tripwire(&root);
    assert!(
        findings.is_empty(),
        "enum_dispatch expands to static dispatch; must not trip Cat-B: {findings:?}"
    );
}

#[test]
fn plain_box_dyn_in_same_file_is_still_reported() {
    let root = temp_vyre_root();
    let source = r#"#[enum_dispatch::enum_dispatch]
pub trait Plugin {
    fn id(&self) -> u32;
}

pub enum Plugins {
    A(u32),
}

impl Plugin for Plugins {
    fn id(&self) -> u32 {
        0
    }
}

pub fn use_dyn(_: Box<dyn Plugin>) {}
"#;
    let path = root.join("runtime").join("enum_dispatch_with_dyn.rs");
    fs::write(&path, source).expect("write fixture");
    let want_line = support::line_of(source, "Box<dyn Plugin>");

    let findings = check_category_b_tripwire(&root);
    support::assert_located(&findings, "trait object (`dyn Trait`)", want_line);
}

#[test]
fn plain_enum_without_macro_is_clean() {
    let root = temp_vyre_root();
    let source = r#"pub enum Kind {
    Fast,
    Slow,
}

pub fn tag(k: Kind) -> u8 {
    match k {
        Kind::Fast => 1,
        Kind::Slow => 2,
    }
}
"#;
    let path = root.join("runtime").join("plain_enum.rs");
    fs::write(&path, source).expect("write fixture");

    let findings = check_category_b_tripwire(&root);
    assert!(
        findings.is_empty(),
        "plain enum must stay clean: {findings:?}"
    );
}