vyre-conform 0.1.0

Conformance suite for vyre backends — proves byte-identical output to CPU reference
Documentation
//! Auto-discovered operation registry.
//!
//! Aggregates every category's `specs()` function into a single collection.
//! Adding a new category module to `specs/` and wiring its `specs()` fn here
//! is the only manual step — the individual categories auto-discover from
//! the core registry.

/// Collect all discovered op specs across every category.
///
/// Each category module walks `vyre::ops::registry` for its prefix and
/// builds conform-side specs automatically. This function merges them all.
#[inline]
pub fn all_specs() -> Vec<crate::OpSpec> {
    let mut specs = Vec::new();
    specs.extend(crate::spec::primitive::specs());
    specs.extend(crate::spec::decode::specs());
    specs.extend(crate::spec::graph::specs());
    specs.extend(crate::spec::hash::specs());
    specs.extend(crate::spec::match_ops::specs());
    specs.extend(crate::spec::string::specs());
    specs
}

/// Result-returning variant of [`all_specs`].
#[inline]
pub fn try_all_specs() -> Result<Vec<crate::OpSpec>, String> {
    Ok(all_specs())
}

/// Collect only compiled in-tree op specs.
#[inline]
pub fn compiled_specs() -> Vec<crate::OpSpec> {
    all_specs()
}

/// Generated golden samples for checked-in generated ops.
#[inline]
pub fn all_generated_golden_samples() -> Vec<vyre_spec::GoldenSample> {
    let mut samples = Vec::new();
    samples.extend_from_slice(crate::spec::decode::base64::GOLDEN);
    samples.extend_from_slice(crate::spec::decode::hex::GOLDEN);
    samples.extend_from_slice(crate::spec::decode::unicode::GOLDEN);
    samples.extend_from_slice(crate::spec::decode::url::GOLDEN);
    samples.extend_from_slice(crate::spec::graph::bfs::GOLDEN);
    samples.extend_from_slice(crate::spec::graph::reachability::GOLDEN);
    samples.extend_from_slice(crate::spec::hash::crc32c::GOLDEN);
    samples.extend_from_slice(crate::spec::hash::fnv1a32::GOLDEN);
    samples.extend_from_slice(crate::spec::hash::murmur3_32::GOLDEN);
    samples.extend_from_slice(crate::spec::match_ops::byte_len::GOLDEN);
    samples.extend_from_slice(crate::spec::match_ops::dfa_scan::GOLDEN);
    samples.extend_from_slice(crate::spec::string::tokenize::GOLDEN);
    // Hand-verified primitive goldens. The primitive ops are
    // macro-generated from a single file; there is no per-op module
    // for the codegen's discover_ops to scan, so we aggregate them
    // here instead.
    samples.extend_from_slice(crate::spec::primitive_goldens::GOLDEN);
    samples
}

/// Generated known-answer vectors for checked-in generated ops.
#[inline]
pub fn all_generated_kat_vectors() -> Vec<vyre_spec::KatVector> {
    let mut vectors = crate::spec::primitive::kat_vectors();
    vectors.extend_from_slice(crate::spec::decode::base64::KAT);
    vectors.extend_from_slice(crate::spec::decode::hex::KAT);
    vectors.extend_from_slice(crate::spec::decode::unicode::KAT);
    vectors.extend_from_slice(crate::spec::decode::url::KAT);
    vectors.extend_from_slice(crate::spec::graph::bfs::KAT);
    vectors.extend_from_slice(crate::spec::graph::reachability::KAT);
    vectors.extend_from_slice(crate::spec::hash::crc32c::KAT);
    vectors.extend_from_slice(crate::spec::hash::fnv1a32::KAT);
    vectors.extend_from_slice(crate::spec::hash::murmur3_32::KAT);
    vectors.extend_from_slice(crate::spec::match_ops::byte_len::KAT);
    vectors.extend_from_slice(crate::spec::match_ops::dfa_scan::KAT);
    vectors.extend_from_slice(crate::spec::string::tokenize::KAT);
    vectors
}

/// Generated adversarial inputs for checked-in generated ops.
#[inline]
pub fn all_generated_adversarial_inputs() -> Vec<vyre_spec::AdversarialInput> {
    let mut inputs = Vec::new();
    inputs.extend_from_slice(crate::spec::decode::base64::ADVERSARIAL);
    inputs.extend_from_slice(crate::spec::decode::hex::ADVERSARIAL);
    inputs.extend_from_slice(crate::spec::decode::unicode::ADVERSARIAL);
    inputs.extend_from_slice(crate::spec::decode::url::ADVERSARIAL);
    inputs.extend_from_slice(crate::spec::graph::bfs::ADVERSARIAL);
    inputs.extend_from_slice(crate::spec::graph::reachability::ADVERSARIAL);
    inputs.extend_from_slice(crate::spec::hash::crc32c::ADVERSARIAL);
    inputs.extend_from_slice(crate::spec::hash::fnv1a32::ADVERSARIAL);
    inputs.extend_from_slice(crate::spec::hash::murmur3_32::ADVERSARIAL);
    inputs.extend_from_slice(crate::spec::match_ops::byte_len::ADVERSARIAL);
    inputs.extend_from_slice(crate::spec::match_ops::dfa_scan::ADVERSARIAL);
    inputs.extend_from_slice(crate::spec::string::tokenize::ADVERSARIAL);
    inputs
}

/// Test-only compatibility hook. The generated registry has no runtime cache.
#[doc(hidden)]
#[inline]
pub fn __clear_cache_for_tests() {}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn all_specs_covers_every_category() {
        let specs = all_specs();
        // Must include primitives + decode + graph + hash + match_ops + string.
        assert!(
            specs.len() > crate::spec::primitive::specs().len(),
            "all_specs() returned {} ops but primitive alone has {}. \
             Other categories are not being included.",
            specs.len(),
            crate::spec::primitive::specs().len()
        );
    }

    #[test]
    fn no_duplicate_op_ids() {
        let specs = all_specs();
        let mut seen = std::collections::HashSet::new();
        for spec in &specs {
            assert!(
                seen.insert(spec.id),
                "duplicate op id in registry: {}",
                spec.id
            );
        }
    }
}