From 9bcf8dd920915786546b627748cfa269b3a032dc Mon Sep 17 00:00:00 2001 From: Aviator 5 Date: Mon, 29 Jun 2026 18:25:35 +0300 Subject: [PATCH] fix(gts-id): return embedded UUID tails - Preserve explicit UUID tail segments in GtsId::to_uuid instead of deriving a namespace UUID. Signed-off-by: Aviator 5 --- .gts-spec-version | 2 +- gts-id/src/gts_id.rs | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/.gts-spec-version b/.gts-spec-version index 9ca265d..60d68b2 100644 --- a/.gts-spec-version +++ b/.gts-spec-version @@ -1 +1 @@ -v0.12.1 +v0.12.2 diff --git a/gts-id/src/gts_id.rs b/gts-id/src/gts_id.rs index 32e3d2c..f00c1a4 100644 --- a/gts-id/src/gts_id.rs +++ b/gts-id/src/gts_id.rs @@ -98,11 +98,12 @@ impl GtsId { .collect() } - /// Generate a deterministic UUID v5 from this GTS ID. + /// Return this GTS ID's UUID. /// - /// The UUID is derived from the validated identifier string under a fixed - /// GTS namespace, so it is stable across processes and runs: the same ID - /// always maps to the same UUID. + /// If the identifier already has a UUID tail, that UUID is returned directly. + /// Otherwise the UUID is derived from the validated identifier string under + /// a fixed GTS namespace, so it is stable across processes and runs: the + /// same ID always maps to the same UUID. /// /// Requires the `uuid` feature. #[cfg(feature = "uuid")] @@ -114,6 +115,10 @@ impl GtsId { static GTS_NS: LazyLock = LazyLock::new(|| uuid::Uuid::new_v5(&uuid::Uuid::NAMESPACE_URL, b"gts")); + if let Some(uuid) = self.segments.last().and_then(GtsIdSegment::uuid) { + return uuid; + } + uuid::Uuid::new_v5(>S_NS, self.id.as_bytes()) } @@ -613,4 +618,30 @@ mod tests { let id2 = GtsId::try_new(>s_id("x.core.events.event.v2~")).expect("test"); assert_ne!(id1.to_uuid(), id2.to_uuid()); } + + #[cfg(feature = "uuid")] + #[test] + fn test_to_uuid_returns_uuid_tail() { + const UUID_TAIL: &str = "7a1d2f34-5678-49ab-9012-abcdef123456"; + let id = + GtsId::try_new(>s_id(&format!("x.core.events.event.v1~{UUID_TAIL}"))).expect("test"); + assert_eq!( + id.to_uuid(), + uuid::Uuid::parse_str(UUID_TAIL).expect("uuid") + ); + } + + #[cfg(feature = "uuid")] + #[test] + fn test_to_uuid_returns_uuid_tail_after_chained_type() { + const UUID_TAIL: &str = "446ef7e5-1a27-4abf-a7c4-f336505c7aa0"; + let id = GtsId::try_new(>s_id(&format!( + "x.core.events.event.v1~acme.orders.events.order.v1~{UUID_TAIL}" + ))) + .expect("test"); + assert_eq!( + id.to_uuid(), + uuid::Uuid::parse_str(UUID_TAIL).expect("uuid") + ); + } }