1use std::sync::atomic::{AtomicI64, Ordering};
8use std::time::{SystemTime, UNIX_EPOCH};
9
10#[derive(Debug)]
15pub struct IdGenerator {
16 counter: AtomicI64,
17}
18
19impl IdGenerator {
20 pub fn new(init: i64) -> Self {
22 Self {
23 counter: AtomicI64::new(init),
24 }
25 }
26
27 pub fn id(&self) -> i64 {
29 self.counter.fetch_add(1, Ordering::SeqCst)
30 }
31
32 pub fn reset(&self, value: i64) {
34 self.counter.store(value, Ordering::SeqCst);
35 }
36
37 pub fn current_value(&self) -> i64 {
39 self.counter.load(Ordering::SeqCst)
40 }
41}
42
43impl Clone for IdGenerator {
44 fn clone(&self) -> Self {
45 Self {
46 counter: AtomicI64::new(self.current_value()),
47 }
48 }
49}
50
51impl Default for IdGenerator {
52 fn default() -> Self {
53 Self::new(0)
54 }
55}
56
57pub fn generate_id() -> u64 {
61 SystemTime::now()
62 .duration_since(UNIX_EPOCH)
63 .expect("Time went backwards")
64 .as_nanos() as u64
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn test_id_generator() {
73 let gen = IdGenerator::new(0);
74
75 assert_eq!(gen.id(), 0);
76 assert_eq!(gen.id(), 1);
77 assert_eq!(gen.id(), 2);
78
79 gen.reset(100);
80 assert_eq!(gen.current_value(), 100);
81 assert_eq!(gen.id(), 100);
82 }
83
84 #[test]
85 fn test_generate_id() {
86 let id1 = generate_id();
87 let id2 = generate_id();
88
89 assert_ne!(id1, id2);
90 }
91}