1use serde::{Serialize, Deserialize};
12use crate::epoch_timestamp;
13
14use num_bigint::BigInt;
15use rand::Rng;
16
17static SEED_LEN: usize = 12;
18#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
21pub struct AlmostSnowflake(String);
22
23pub fn bigint(input: usize) -> BigInt {
24 BigInt::from(input)
25}
26
27impl AlmostSnowflake {
28 pub fn new(server_id: usize) -> Self {
30 let mut bytes = String::new();
32
33 let mut rng = rand::rng();
34 for _ in 1..=SEED_LEN {
35 bytes.push_str(&rng.random_range(0..10).to_string())
36 }
37
38 let mut id = bigint(epoch_timestamp(2024) as usize) << 22_u128;
40 id |= bigint((server_id % 1024) << 12);
41 id |= bigint((bytes.parse::<usize>().unwrap() + 1) % 4096);
42
43 Self(id.to_string())
45 }
46}
47
48impl std::fmt::Display for AlmostSnowflake {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 write!(f, "{}", self.0)
51 }
52}