| 1 | //! UUIDv7 identifiers. | |
| 2 | //! | |
| 3 | //! Spec §5: "UUIDv7 primary keys throughout — time-ordered, index-friendly, and | |
| 4 | //! they don't leak counts." Generated in the application rather than by the | |
| 5 | //! database so an id is known before insert. | |
| 6 | ||
| 7 | use uuid::Uuid; | |
| 8 | ||
| 9 | /// Mint a new time-ordered identifier. | |
| 10 | pub fn new_id() -> Uuid { | |
| 11 | Uuid::now_v7() | |
| 12 | } | |
| 13 | ||
| 14 | #[cfg(test)] | |
| 15 | mod tests { | |
| 16 | use super::*; | |
| 17 | ||
| 18 | #[test] | |
| 19 | fn ids_are_version_7() { | |
| 20 | assert_eq!(new_id().get_version_num(), 7); | |
| 21 | } | |
| 22 | ||
| 23 | #[test] | |
| 24 | fn ids_are_time_ordered() { | |
| 25 | // The property that makes these index-friendly: successive ids sort in | |
| 26 | // creation order, so btree inserts stay at the right edge of the tree. | |
| 27 | let mut prev = new_id(); | |
| 28 | for _ in 0..1000 { | |
| 29 | let next = new_id(); | |
| 30 | assert!( | |
| 31 | next > prev, | |
| 32 | "uuidv7 must be monotonically increasing: {prev} then {next}" | |
| 33 | ); | |
| 34 | prev = next; | |
| 35 | } | |
| 36 | } | |
| 37 | ||
| 38 | #[test] | |
| 39 | fn ids_are_unique() { | |
| 40 | use std::collections::HashSet; | |
| 41 | let set: HashSet<Uuid> = (0..10_000).map(|_| new_id()).collect(); | |
| 42 | assert_eq!(set.len(), 10_000); | |
| 43 | } | |
| 44 | } |
44 lines · Rust