#[must_use]
pub fn stable_id(text: &str) -> u64 {
velesdb_core::hash_id(text)
}
#[cfg(feature = "context")]
#[must_use]
pub fn stable_id_bytes(bytes: &[u8]) -> u64 {
velesdb_core::hash_id_bytes(bytes)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn same_input_yields_same_id() {
assert_eq!(stable_id("hello"), stable_id("hello"));
}
#[test]
fn different_inputs_yield_different_ids() {
assert_ne!(stable_id("hello"), stable_id("world"));
}
#[test]
fn empty_string_yields_offset_basis() {
assert_eq!(stable_id(""), 0xcbf2_9ce4_8422_2325);
}
#[cfg(feature = "context")]
#[test]
fn stable_id_bytes_agrees_with_stable_id_on_valid_utf8() {
assert_eq!(stable_id_bytes("hello".as_bytes()), stable_id("hello"));
}
#[cfg(feature = "context")]
#[test]
fn stable_id_bytes_hashes_non_utf8_bytes() {
let bytes = [0xFFu8, 0x00, 0x89, 0x50, 0x4E, 0x47];
assert_eq!(stable_id_bytes(&bytes), stable_id_bytes(&bytes));
assert_ne!(stable_id_bytes(&bytes), stable_id_bytes(&bytes[1..]));
}
#[test]
fn stable_id_golden_vectors_unchanged_by_delegation() {
let vectors: &[(&str, u64)] = &[
("", 0xcbf2_9ce4_8422_2325),
("a", 0xaf63_dc4c_8601_ec8c),
("hello", 0xa430_d846_80aa_bd0b),
("world", 0x4f59_ff5e_730c_8af3),
("tenant:acme", 0x434a_088f_8b77_5207),
("café", 0x48e8_823a_cfa4_0d89),
("日本語", 0xee9e_e2b5_c854_ef87),
("emoji:🚀", 0x5063_383e_8fb5_57fa),
("mixed-Ünïcödé-42", 0x3019_47e7_0a3d_8809),
("fact:the sky is blue", 0x5ff1_6ac5_c3bf_e13b),
];
for (input, expected) in vectors {
assert_eq!(
stable_id(input),
*expected,
"stable_id({input:?}) drifted from its pre-refactor golden vector"
);
#[cfg(feature = "context")]
assert_eq!(
stable_id_bytes(input.as_bytes()),
*expected,
"stable_id_bytes({input:?}) drifted from its pre-refactor golden vector"
);
}
}
}