rusty_snowflake/generator.rs
1use super::Snowflake;
2
3#[derive(Debug, Clone, Copy, Eq, PartialEq)]
4/// A snowflake generator that can be used to generate snowflake IDs.
5pub struct SnowflakeGenerator {
6 /// The last snowflake ID generated by the generator.
7 pub last_snowflake: Snowflake,
8}
9
10impl SnowflakeGenerator {
11 /// Create a new snowflake generator with the given worker ID
12 ///
13 /// # Arguments
14 /// * `worker_id` - The worker ID of the snowflake generator
15 ///
16 /// # Returns
17 /// A new `SnowflakeGenerator`
18 ///
19 /// # Example
20 /// ```rust
21 /// use rusty_snowflake::{SnowflakeGenerator, Snowflake};
22 ///
23 /// const WORKER_ID: u64 = 420;
24 ///
25 /// let generator = SnowflakeGenerator::new(WORKER_ID);
26 ///
27 /// assert_eq!(generator.last_snowflake, Snowflake::new(WORKER_ID));
28 /// ```
29 pub fn new(worker_id: u64) -> SnowflakeGenerator {
30 SnowflakeGenerator {
31 last_snowflake: Snowflake::new(worker_id),
32 }
33 }
34
35 /// Start at the given snowflake
36 ///
37 /// # Arguments
38 /// * `snowflake` - The snowflake to start at
39 ///
40 /// # Returns
41 /// A `SnowflakeGenerator`
42 ///
43 /// # Example
44 /// ```rust
45 /// use rusty_snowflake::{Snowflake, SnowflakeGenerator};
46 ///
47 /// const WORKER_ID: u64 = 420;
48 ///
49 /// let generator = SnowflakeGenerator::start_at(&Snowflake::new(WORKER_ID));
50 ///
51 /// assert_eq!(generator.last_snowflake, Snowflake::new(WORKER_ID));
52 /// ```
53 pub fn start_at(snowflake: &Snowflake) -> SnowflakeGenerator {
54 SnowflakeGenerator {
55 last_snowflake: *snowflake,
56 }
57 }
58
59 /// Generates the next snowflake ID and returns a reference to it.
60 ///
61 /// This method generates the next snowflake ID by updating the `last_snowflake` stored in the generator.
62 /// It increments the sequence number and, if necessary, adjusts the timestamp to ensure uniqueness.
63 /// The generated snowflake ID is then returned as a reference.
64 ///
65 /// # Examples
66 ///
67 /// ```rust
68 /// use rusty_snowflake::SnowflakeGenerator;
69 ///
70 /// let mut generator = SnowflakeGenerator::new(420);
71 ///
72 /// // Generate the next snowflake ID
73 /// let snowflake = generator.next();
74 /// println!("Generated snowflake ID: {:?}", snowflake);
75 /// ```
76 ///
77 /// # Returns
78 ///
79 /// A reference to the generated snowflake ID.
80 ///
81 /// # Panics
82 ///
83 /// This method does not panic.
84 pub fn next(&mut self) -> &Snowflake {
85 self.last_snowflake = self.last_snowflake.next();
86 &self.last_snowflake
87 }
88
89 /// Get the current timestamp in seconds since the epoch (1970-01-01 00:00:00 UTC).
90 ///
91 /// # Returns
92 /// The current timestamp in seconds
93 pub fn get_timestamp() -> u64 {
94 std::time::SystemTime::now()
95 .duration_since(std::time::UNIX_EPOCH)
96 .expect("SystemTime before UNIX EPOCH!")
97 .as_secs()
98 }
99
100 /// Wait for the next second and return the timestamp
101 ///
102 /// # Arguments
103 /// * `current_timestamp` - The current timestamp in seconds
104 ///
105 /// # Returns
106 /// The timestamp of the next second
107 pub fn wait_next_timestamp(last_timestamp: u64) -> u64 {
108 let mut timestamp = SnowflakeGenerator::get_timestamp();
109 while timestamp <= last_timestamp {
110 std::thread::sleep(std::time::Duration::from_millis(1));
111 timestamp = SnowflakeGenerator::get_timestamp();
112 }
113 timestamp
114 }
115}
116
117#[cfg(test)]
118mod tests {
119
120 use super::*;
121
122 #[test]
123 fn test_new() {
124 let generator = SnowflakeGenerator::new(420);
125 assert_eq!(generator.last_snowflake, Snowflake::new(420));
126
127 let generator = SnowflakeGenerator::new(69);
128 assert_eq!(generator.last_snowflake, Snowflake::new(69));
129 }
130
131 #[test]
132 fn test_start_at() {
133 let snowflake = Snowflake::new(420);
134 let generator = SnowflakeGenerator::start_at(&snowflake);
135 assert_eq!(generator.last_snowflake, snowflake);
136 }
137
138 #[test]
139 fn test_next() {
140 let mut generator = SnowflakeGenerator::new(420);
141
142 for _ in 0..10 {
143 let snowflake = *generator.next();
144 assert_eq!(snowflake, generator.last_snowflake);
145 }
146 }
147
148 #[test]
149 fn test_eq() {
150 let gen1 = SnowflakeGenerator::new(420);
151 let gen2 = SnowflakeGenerator::new(420);
152 assert_eq!(gen1, gen2);
153
154 let gen1 = Snowflake::new(420);
155 let gen2 = Snowflake::new(69);
156 assert_ne!(gen1, gen2);
157 }
158
159 #[test]
160 fn test_snowflake_wait_next_timestamp() {
161 let timestamp = SnowflakeGenerator::get_timestamp();
162
163 let next = SnowflakeGenerator::wait_next_timestamp(timestamp);
164
165 assert!(
166 next > timestamp,
167 "Snowflake.wait_next_timestamp didn't return a new timestamp"
168 );
169 }
170
171 #[test]
172 fn test_get_timestamp() {
173 let timestamp = SnowflakeGenerator::get_timestamp();
174
175 assert!(
176 timestamp
177 == std::time::SystemTime::now()
178 .duration_since(std::time::UNIX_EPOCH)
179 .unwrap()
180 .as_secs()
181 );
182 }
183}