use crate::spec::types::OpSpec;
#[inline]
pub fn compute_registry_hash(specs: &[OpSpec]) -> [u8; 32] {
let mut hasher = blake3::Hasher::new();
hasher.update(b"vyre-conform-registry-hash-v1");
let mut order: Vec<usize> = (0..specs.len()).collect();
order.sort_by_key(|&idx| specs[idx].id);
for idx in order {
let spec = &specs[idx];
hash_bytes(&mut hasher, spec.id.as_bytes());
hasher.update(&(u64::from(spec.version)).to_le_bytes());
let mut law_names: Vec<&str> = spec.laws.iter().map(|law| law.name()).collect();
law_names.sort_unstable();
for name in law_names {
hash_bytes(&mut hasher, name.as_bytes());
}
for input in &spec.signature.inputs {
hash_bytes(&mut hasher, input.to_string().as_bytes());
}
hash_bytes(&mut hasher, spec.signature.output.to_string().as_bytes());
let wgsl_source = (spec.wgsl_fn)();
hash_bytes(&mut hasher, wgsl_source.as_bytes());
}
*hasher.finalize().as_bytes()
}
fn hash_bytes(hasher: &mut blake3::Hasher, bytes: &[u8]) {
hasher.update(&(bytes.len() as u64).to_le_bytes());
hasher.update(bytes);
}