1use std::sync::atomic::{AtomicI64, Ordering};
10use std::thread;
11use std::time::SystemTime;
12
13use chrono::{DateTime, Utc};
14use grammers_tl_types as tl;
15
16static LAST_ID: AtomicI64 = AtomicI64::new(0);
20
21pub(crate) fn generate_random_id() -> i64 {
23 while LAST_ID.load(Ordering::SeqCst) == 0 {
24 let now = SystemTime::now()
25 .duration_since(SystemTime::UNIX_EPOCH)
26 .expect("system time is before epoch")
27 .as_nanos() as i64;
28
29 if LAST_ID
30 .compare_exchange(0, now, Ordering::SeqCst, Ordering::SeqCst)
31 .is_err()
32 {
33 thread::yield_now();
34 }
35 }
36
37 LAST_ID.fetch_add(1, Ordering::SeqCst)
38}
39
40pub(crate) fn generate_random_ids(n: usize) -> Vec<i64> {
41 (0..n).map(|_| generate_random_id()).collect()
42}
43
44pub(crate) fn date(date: i32) -> DateTime<Utc> {
45 DateTime::<Utc>::from_timestamp(date as i64, 0).expect("date out of range")
46}
47
48pub(crate) fn extract_password_parameters(
49 current_algo: &tl::enums::PasswordKdfAlgo,
50) -> (&Vec<u8>, &Vec<u8>, &Vec<u8>, &i32) {
51 let tl::types::PasswordKdfAlgoSha256Sha256Pbkdf2Hmacsha512iter100000Sha256ModPow {
52 salt1,
53 salt2,
54 p,
55 g,
56 } = match current_algo {
57 tl::enums::PasswordKdfAlgo::Unknown => panic!(
58 "Unknown KDF (most likely, the client is outdated and does not support the specified KDF algorithm)"
59 ),
60 tl::enums::PasswordKdfAlgo::Sha256Sha256Pbkdf2Hmacsha512iter100000Sha256ModPow(alg) => alg,
61 };
62 (salt1, salt2, p, g)
63}
64
65pub(crate) fn peer_from_message(message: &tl::enums::Message) -> Option<tl::enums::Peer> {
66 match &message {
67 tl::enums::Message::Empty(message) => message.peer_id.clone(),
68 tl::enums::Message::Message(message) => Some(message.peer_id.clone()),
69 tl::enums::Message::Service(message) => Some(message.peer_id.clone()),
70 }
71}