1use crate::constants::TWITTER_EPOCH_START;
2use once_cell::sync::Lazy;
3use std::sync::atomic::{AtomicBool, AtomicU16, AtomicU64, Ordering};
4use std::sync::Arc;
5
6pub static CONTEXT: Lazy<Arc<Context>> = Lazy::new(|| Arc::new(Context::new()));
7
8pub struct Context {
9 pub epoch_start: AtomicU64,
10 pub sequence: AtomicU16,
11 pub instance: AtomicU16,
12 pub sequence_autoincrement: AtomicBool,
13}
14
15impl Context {
16 fn new() -> Self {
17 Self {
18 epoch_start: AtomicU64::new(TWITTER_EPOCH_START),
19 instance: AtomicU16::new((std::process::id() & 0x3FF) as u16),
20 sequence: AtomicU16::new(0),
21 sequence_autoincrement: AtomicBool::new(true),
22 }
23 }
24}
25
26pub fn sequence_increment() {
27 CONTEXT.sequence.store(
28 (CONTEXT.sequence.load(Ordering::Relaxed) + 1) & 0xFFF,
29 Ordering::Relaxed,
30 );
31}
32
33pub fn set_instance(instance: u16) {
34 CONTEXT.instance.store(instance, Ordering::Relaxed);
35}
36
37pub fn set_sequence(sequence: u16) {
38 CONTEXT.sequence.store(sequence, Ordering::Relaxed);
39}
40
41pub fn set_sequence_autoincrement(sequence_autoincrement: bool) {
44 CONTEXT
45 .sequence_autoincrement
46 .store(sequence_autoincrement, Ordering::Relaxed);
47}
48
49pub fn set_epoch(epoch: u64) {
50 CONTEXT.epoch_start.store(epoch, Ordering::Relaxed);
52}