use std::any::type_name;
use std::mem::{align_of, size_of};
pub const fn fnv1a64(bytes: &[u8]) -> u64 {
let mut hash = 0xcbf2_9ce4_8422_2325u64;
let mut i = 0;
while i < bytes.len() {
hash ^= bytes[i] as u64;
hash = hash.wrapping_mul(0x0100_0000_01b3);
i += 1;
}
hash
}
fn short_type_name(full: &str) -> String {
let mut out = String::with_capacity(full.len());
let mut ident = String::new();
let mut chars = full.chars().peekable();
while let Some(c) = chars.next() {
if c.is_alphanumeric() || c == '_' {
ident.push(c);
} else if c == ':' && chars.peek() == Some(&':') {
chars.next();
ident.clear();
} else {
out.push_str(&ident);
ident.clear();
out.push(c);
}
}
out.push_str(&ident);
out
}
pub fn compute_layout_signature<T: 'static>() -> u64 {
let name = short_type_name(type_name::<T>());
let size = size_of::<T>();
let align = align_of::<T>();
let mut buf = Vec::with_capacity(name.len() + 16);
buf.extend_from_slice(name.as_bytes());
buf.extend_from_slice(&size.to_le_bytes());
buf.extend_from_slice(&align.to_le_bytes());
fnv1a64(&buf)
}
pub trait LayoutSignature: 'static {
fn layout_signature() -> u64;
}
impl<T: 'static> LayoutSignature for T {
#[inline]
fn layout_signature() -> u64 {
compute_layout_signature::<T>()
}
}
#[cfg(test)]
#[path = "../tests/unit/signature.rs"]
mod tests;