#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct CryptomatteEntry {
pub name: String,
pub hash: u32,
pub coverage: f32,
}
pub fn cryptomatte_name_to_hash(name: &str) -> u32 {
let mut hash: u32 = 2_166_136_261;
for byte in name.bytes() {
hash ^= byte as u32;
hash = hash.wrapping_mul(16_777_619);
}
hash
}
pub fn new_cryptomatte_entry(name: &str, coverage: f32) -> CryptomatteEntry {
CryptomatteEntry {
name: name.to_string(),
hash: cryptomatte_name_to_hash(name),
coverage,
}
}
pub fn cryptomatte_to_json(e: &CryptomatteEntry) -> String {
format!(
"{{\"name\":\"{}\",\"hash\":{},\"coverage\":{}}}",
e.name, e.hash, e.coverage
)
}
pub fn cryptomatte_entries_to_json(entries: &[CryptomatteEntry]) -> String {
let inner: Vec<String> = entries.iter().map(cryptomatte_to_json).collect();
format!("[{}]", inner.join(","))
}
pub fn cryptomatte_coverage_sum(entries: &[CryptomatteEntry]) -> f32 {
entries.iter().map(|e| e.coverage).sum()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fnv1a_known() {
let h = cryptomatte_name_to_hash("");
assert_eq!(h, 2_166_136_261);
}
#[test]
fn test_new_cryptomatte_entry() {
let e = new_cryptomatte_entry("Sphere", 0.8);
assert_eq!(e.name, "Sphere");
assert!(e.hash > 0);
}
#[test]
fn test_cryptomatte_to_json() {
let e = new_cryptomatte_entry("Cube", 0.5);
let j = cryptomatte_to_json(&e);
assert!(j.contains("Cube"));
}
#[test]
fn test_cryptomatte_entries_to_json() {
let entries = vec![
new_cryptomatte_entry("A", 0.3),
new_cryptomatte_entry("B", 0.7),
];
let j = cryptomatte_entries_to_json(&entries);
assert!(j.starts_with('['));
}
#[test]
fn test_cryptomatte_coverage_sum() {
let entries = vec![
new_cryptomatte_entry("A", 0.3),
new_cryptomatte_entry("B", 0.7),
];
let s = cryptomatte_coverage_sum(&entries);
assert!((s - 1.0).abs() < 1e-5);
}
}