use std::panic::Location;
use topcoat_core::fnv1a::Fnv1a;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SiteKey(pub(super) u64);
impl SiteKey {
#[must_use]
pub const fn new(file: &str, line: u32, column: u32, ordinal: u32) -> Self {
Self(
Fnv1a::<u64>::new()
.write(file.as_bytes())
.write(b"\0")
.write(&line.to_le_bytes())
.write(&column.to_le_bytes())
.write(&ordinal.to_le_bytes())
.finish(),
)
}
#[must_use]
pub const fn from_location(location: &Location<'_>) -> Self {
Self::new(location.file(), location.line(), location.column(), 0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn site_keys_at_distinct_locations_differ() {
let base = SiteKey::new("src/a.rs", 1, 1, 0);
assert_ne!(base, SiteKey::new("src/b.rs", 1, 1, 0));
assert_ne!(base, SiteKey::new("src/a.rs", 2, 1, 0));
assert_ne!(base, SiteKey::new("src/a.rs", 1, 2, 0));
assert_ne!(base, SiteKey::new("src/a.rs", 1, 1, 1));
}
#[test]
fn a_location_keys_like_its_coordinates() {
let location = Location::caller();
assert_eq!(
SiteKey::from_location(location),
SiteKey::new(location.file(), location.line(), location.column(), 0),
);
}
}