use uuid::Uuid;
pub const DEFAULT_NAMESPACE: Uuid = Uuid::from_bytes([
0x6f, 0x63, 0x1b, 0x9a, 0x2d, 0x4c, 0x5e, 0x11, 0x9b, 0x21, 0x3f, 0x8a, 0xc0, 0x7e, 0x44, 0x21,
]);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum Wrap {
#[default]
UuidV5Namespaced,
UuidV5With(Uuid),
UuidV3Nil,
Passthrough,
}
impl Wrap {
#[must_use]
pub fn apply(self, raw: &str) -> Option<Uuid> {
match self {
Self::UuidV5Namespaced => Some(Uuid::new_v5(&DEFAULT_NAMESPACE, raw.as_bytes())),
Self::UuidV5With(ns) => Some(Uuid::new_v5(&ns, raw.as_bytes())),
Self::UuidV3Nil => Some(Uuid::new_v3(&Uuid::nil(), raw.as_bytes())),
Self::Passthrough => Uuid::parse_str(raw).ok(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn v5_default_is_deterministic() {
let a = Wrap::UuidV5Namespaced.apply("host-x").unwrap();
let b = Wrap::UuidV5Namespaced.apply("host-x").unwrap();
assert_eq!(a, b);
}
#[test]
fn v5_distinct_namespaces_produce_distinct_uuids() {
let ns = Uuid::from_bytes([1; 16]);
let a = Wrap::UuidV5Namespaced.apply("host-x").unwrap();
let b = Wrap::UuidV5With(ns).apply("host-x").unwrap();
assert_ne!(a, b);
}
#[test]
fn passthrough_roundtrips_valid_uuid() {
let uuid = "12345678-1234-1234-1234-123456789abc";
assert_eq!(Wrap::Passthrough.apply(uuid), Uuid::parse_str(uuid).ok());
}
#[test]
fn passthrough_rejects_non_uuid() {
assert_eq!(Wrap::Passthrough.apply("not-a-uuid"), None);
}
#[test]
fn v3_nil_matches_go_legacy_derivation() {
let expected = Uuid::new_v3(&Uuid::nil(), b"host-x");
assert_eq!(Wrap::UuidV3Nil.apply("host-x"), Some(expected));
}
#[test]
fn v3_nil_is_deterministic() {
let a = Wrap::UuidV3Nil.apply("host-x").unwrap();
let b = Wrap::UuidV3Nil.apply("host-x").unwrap();
assert_eq!(a, b);
}
#[test]
fn non_passthrough_strategies_always_return_some() {
let ns = Uuid::from_bytes([1; 16]);
let inputs = ["", " \n", &"a".repeat(10_000)];
for input in inputs {
assert!(Wrap::UuidV5Namespaced.apply(input).is_some());
assert!(Wrap::UuidV5With(ns).apply(input).is_some());
assert!(Wrap::UuidV3Nil.apply(input).is_some());
}
}
}