#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
pub enum ProjectionId {
Splat,
Kuramoto,
Expert,
Graph,
Thermal,
}
impl ProjectionId {
pub fn type_hash(self) -> u32 {
match self {
ProjectionId::Splat => 0x5A1A_0001,
ProjectionId::Kuramoto => 0x4B55_0002,
ProjectionId::Expert => 0x3E58_0003,
ProjectionId::Graph => 0x4752_0004,
ProjectionId::Thermal => 0x5448_0005,
}
}
}
pub trait Projection: Sized {
fn byte_size() -> usize;
fn id() -> ProjectionId;
fn read(buf: &[u8]) -> Self;
fn write(&self, buf: &mut [u8]);
fn shape_hash_contribution(&self) -> u32;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_projection_id_type_hash_unique() {
let ids = [
ProjectionId::Splat,
ProjectionId::Kuramoto,
ProjectionId::Expert,
ProjectionId::Graph,
ProjectionId::Thermal,
];
let hashes: Vec<u32> = ids.iter().map(|id| id.type_hash()).collect();
for i in 0..hashes.len() {
for j in (i + 1)..hashes.len() {
assert_ne!(hashes[i], hashes[j], "Hash collision between {:?} and {:?}", ids[i], ids[j]);
}
}
}
}