vyre-conform 0.1.0

Conformance suite for vyre backends — proves byte-identical output to CPU reference
Documentation
pub use super::boundary::BoundaryLengths;
pub use super::edge_cases::EdgeCases;
pub use super::exhaustive::ExhaustiveByteRange;
pub use super::pathological::Pathological;
pub use super::random::RandomUniform;
pub use super::u32_pathological::U32Pathological;
use crate::spec::types::OpSignature;

/// Generates deterministic inputs based on an op's type signature and identity.
///
/// Generators produce inputs based on the signature's input types. The `op_id`
/// parameter enables op-specific edge case generation (e.g., shift-by-32 for
/// `shl`, offset+count > 32 for `extract_bits`).
///
/// Adding a new `DataType` or signature shape never requires modifying existing
/// generators — they simply return empty for shapes they don't handle.
pub trait InputGenerator: Send + Sync {
    /// Human-readable name for this generator (used in failure reports).
    fn name(&self) -> &str;

    /// Whether this generator can produce inputs for the given signature.
    fn handles(&self, signature: &OpSignature) -> bool;

    /// Generate labeled inputs for the given signature.
    /// Returns (label, bytes) pairs. Label is human-readable for failure reports.
    /// Same signature + same seed = same outputs. Deterministic always.
    fn generate(&self, signature: &OpSignature, seed: u64) -> Vec<(String, Vec<u8>)>;

    /// Generate labeled inputs with knowledge of which op is being tested.
    ///
    /// Override this to produce op-specific edge cases. The default delegates
    /// to `generate()`, ignoring the op ID — backwards compatible with all
    /// existing generators.
    fn generate_for_op(
        &self,
        op_id: &str,
        signature: &OpSignature,
        seed: u64,
    ) -> Vec<(String, Vec<u8>)> {
        let _ = op_id;
        self.generate(signature, seed)
    }

    /// Emit labeled inputs without requiring the caller to retain them all.
    ///
    /// Large-scale generators should override this method and call `emit` one
    /// case at a time. The default preserves existing generators by delegating
    /// to [`InputGenerator::generate_for_op`].
    fn generate_for_op_streaming(
        &self,
        op_id: &str,
        signature: &OpSignature,
        seed: u64,
        emit: &mut dyn FnMut(String, Vec<u8>),
    ) {
        for (label, bytes) in self.generate_for_op(op_id, signature, seed) {
            emit(label, bytes);
        }
    }
}