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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use {
chrono::{DateTime, TimeZone, Utc},
rand::random,
serde::{Deserialize, Deserializer, Serialize, Serializer},
std::{
fmt::{Display, Formatter, Result as FmtResult},
str::FromStr,
time::SystemTime,
},
uuid::Uuid,
};
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct RequestId {
id: Uuid,
}
impl RequestId {
pub fn new() -> Self {
let now = SystemTime::now();
let offset = match now.duration_since(SystemTime::UNIX_EPOCH) {
Ok(offset) => offset,
Err(_) => SystemTime::UNIX_EPOCH
.duration_since(now)
.expect("SystemTime cannot be represented as a duration since the Unix epoch"),
};
let timestamp = offset.as_secs();
Self::from_timestamp(timestamp as i64)
}
pub fn from_timestamp_and_random(unix_timestamp: i64, random: u64) -> Self {
let mut bytes = [0u8; 16];
bytes[0..8].copy_from_slice(&unix_timestamp.to_be_bytes());
bytes[8..16].copy_from_slice(&random.to_be_bytes());
Self {
id: Uuid::from_bytes(bytes),
}
}
pub fn from_datetime_and_random<Tz: TimeZone>(datetime: DateTime<Tz>, random: u64) -> Self {
let unix_timestamp = datetime.timestamp();
Self::from_timestamp_and_random(unix_timestamp, random)
}
pub fn from_timestamp(unix_timestamp: i64) -> Self {
let random: u64 = random();
Self::from_timestamp_and_random(unix_timestamp, random)
}
pub fn from_datetime<Tz: TimeZone>(datetime: DateTime<Tz>) -> Self {
let unix_timestamp = datetime.timestamp();
Self::from_timestamp(unix_timestamp)
}
#[inline]
pub fn unix_timestamp(&self) -> u64 {
u64::from_be_bytes(self.id.as_bytes()[0..8].try_into().unwrap())
}
#[inline]
pub fn datetime(&self) -> DateTime<Utc> {
Utc.timestamp_opt(self.unix_timestamp() as i64, 0).unwrap()
}
#[inline]
pub fn uuid(&self) -> Uuid {
self.id
}
}
impl Default for RequestId {
fn default() -> Self {
Self::new()
}
}
impl Display for RequestId {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "{}", self.id)
}
}
impl<'de> Deserialize<'de> for RequestId {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(RequestId {
id: Uuid::deserialize(deserializer)?,
})
}
}
impl FromStr for RequestId {
type Err = uuid::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(RequestId {
id: Uuid::parse_str(s)?,
})
}
}
impl Serialize for RequestId {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.id.to_string())
}
}