semantic_id/state16/
mod.rs

1use rand::Rng;
2use std::{
3    sync::{LazyLock, Mutex},
4    time::SystemTime,
5};
6
7pub static ID_STATE16: LazyLock<Mutex<GenerateState16>> = LazyLock::new(|| Mutex::new(GenerateState16::default()));
8
9pub struct GenerateState16 {
10    machine_id: u8,
11    sequence: u8,
12}
13
14impl Default for GenerateState16 {
15    fn default() -> Self {
16        let machine_id = match std::env::var("MACHINE_ID") {
17            Ok(o) => {
18                let id = u64::from_str_radix(o.as_str(), 10).expect("`MACHINE_ID` must be a integer");
19                (id % 0x100) as u8
20            }
21            Err(_) => rand::rng().random::<u8>(),
22        };
23        Self { machine_id, sequence: 0 }
24    }
25}
26
27impl GenerateState16 {
28    /// Construct the ID: 48 bits timestamp | 8 bits machine ID | 8 bits sequence in 1ms
29    pub fn generate64_now(&mut self) -> u64 {
30        let timestamp = SystemTime::now() //
31            .duration_since(SystemTime::UNIX_EPOCH)
32            .expect("Time went backwards")
33            .as_millis() as u64;
34        self.generate64_by(timestamp)
35    }
36    pub fn generate64_by(&mut self, unix: u64) -> u64 {
37        let ms = unix << 16; // 32 bit
38        // println!("{:016x}", ms);
39        let machine_id = (self.machine_id as u64) << 8; // 8bit
40        // println!("{:016x}", machine_id);
41        let sequence = self.sequence as u64; // 8 bit
42        // println!("{:016x}", sequence);
43        self.sequence = self.sequence.wrapping_add(1);
44        ms | machine_id | sequence
45    }
46}