1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use crate::errors::{ValidationError, ValidationResult};
use chrono::offset::Utc;
use lazy_static::lazy_static;
use uuid::v1::{Context, Timestamp};
use uuid::Uuid;
const NODE_ID: [u8; 6] = [0, 0, 0, 0, 0, 0];
lazy_static! {
static ref CONTEXT: Context = Context::new(0);
}
pub fn generate_uuid_v1() -> Uuid {
let now = Utc::now();
let ts = Timestamp::from_unix(&*CONTEXT, now.timestamp() as u64, now.timestamp_subsec_nanos());
Uuid::new_v1(ts, &NODE_ID).expect("Expected to be able to generate a UUID")
}
pub(crate) fn next_uuid(uuid: Uuid) -> ValidationResult<Uuid> {
let mut bytes = *uuid.as_bytes();
for i in (0..16).rev() {
if bytes[i] < 255 {
bytes[i] += 1;
return Ok(Uuid::from_slice(&bytes[..]).unwrap());
} else {
bytes[i] = 0;
}
}
Err(ValidationError::CannotIncrementUuid)
}
#[cfg(test)]
mod tests {
use super::{generate_uuid_v1, next_uuid};
use core::str::FromStr;
use uuid::Uuid;
#[test]
fn should_generate_new_uuid_v1() {
let first = generate_uuid_v1();
let second = generate_uuid_v1();
assert_ne!(first, second);
}
#[test]
fn should_generate_next_uuid() {
let result = next_uuid(Uuid::from_str("16151dea-a538-4bf1-9559-851e256cf139").unwrap());
assert!(result.is_ok());
assert_eq!(
result.unwrap(),
Uuid::from_str("16151dea-a538-4bf1-9559-851e256cf13a").unwrap()
);
let from_uuid = Uuid::from_str("ffffffff-ffff-ffff-ffff-ffffffffffff").unwrap();
assert!(next_uuid(from_uuid).is_err());
}
}