xref: /xiu/library/streamhub/src/utils.rs (revision b36cf5da)
1 use rand::Rng;
2 use std::fmt;
3 use std::time::SystemTime;
4 
5 #[derive(Debug, Clone, Eq, PartialEq, Hash, Default, Copy)]
6 pub struct Uuid {
7     value: [char; 16],
8     random_count: RandomDigitCount,
9 }
10 
11 #[derive(Debug, Clone, Eq, PartialEq, Hash, Default, Copy)]
12 pub enum RandomDigitCount {
13     #[default]
14     Zero = 0,
15     One = 1,
16     Two = 2,
17     Three = 3,
18     Four = 4,
19     Five = 5,
20     Six = 6,
21 }
22 
u8_to_enum(digit: u8) -> RandomDigitCount23 fn u8_to_enum(digit: u8) -> RandomDigitCount {
24     match digit {
25         0 => RandomDigitCount::Zero,
26         1 => RandomDigitCount::One,
27         2 => RandomDigitCount::Two,
28         3 => RandomDigitCount::Three,
29         4 => RandomDigitCount::Four,
30         5 => RandomDigitCount::Five,
31         6 => RandomDigitCount::Six,
32         _ => RandomDigitCount::Zero,
33     }
34 }
35 
36 impl Uuid {
from_str2(uuid: &String) -> Option<Uuid>37     pub fn from_str2(uuid: &String) -> Option<Uuid> {
38         let length = uuid.len();
39         if !(10..=16).contains(&length) {
40             return None;
41         }
42 
43         let random_count = u8_to_enum(length as u8 - 10);
44         let mut value: [char; 16] = ['\0'; 16];
45         for (i, c) in uuid.chars().enumerate() {
46             value[i] = c;
47         }
48 
49         Some(Uuid {
50             value,
51             random_count,
52         })
53     }
new(random_digit_count: RandomDigitCount) -> Self54     pub fn new(random_digit_count: RandomDigitCount) -> Self {
55         let duration = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH);
56         let seconds = match duration {
57             Ok(result) => result.as_secs(),
58             _ => 0,
59         };
60 
61         let seconds_str = seconds.to_string();
62         let mut value: [char; 16] = ['\0'; 16];
63         for (i, c) in seconds_str.chars().enumerate() {
64             if i >= 10 {
65                 break;
66             }
67             value[i] = c;
68         }
69 
70         let mut rng = rand::thread_rng();
71         let random_size = random_digit_count as usize;
72         for i in 0..random_size {
73             let number = rng.gen_range(0..=9);
74             if let Some(c) = std::char::from_digit(number, 10) {
75                 value[10 + i] = c;
76             }
77         }
78 
79         // let count = random_digit_count as u8;
80         // let mut rng = rand::thread_rng();
81         // let random_digit_str: String = (0..count)
82         //     .map(|_| rng.gen_range(0..=9).to_string())
83         //     .collect();
84 
85         // let seconds_str = format!("{}", seconds);
86         // let random_num_str = if count > 0 {
87         //     format!("-{}", random_digit_str)
88         // } else {
89         //     String::from("")
90         // };
91 
92         Self {
93             value,
94             random_count: random_digit_count,
95         }
96     }
97 }
98 
99 impl fmt::Display for Uuid {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result100     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
101         let val: String = self
102             .value
103             .iter()
104             .take(10 + self.random_count as usize)
105             .collect();
106         write!(f, "{}", &val)
107     }
108 }
109 
110 #[cfg(test)]
111 mod tests {
112     use super::Uuid;
113 
114     #[test]
test_uuid()115     fn test_uuid() {
116         let id = Uuid::new(super::RandomDigitCount::Four);
117 
118         let s = id.to_string();
119 
120         println!("{s}");
121 
122         if let Some(u) = Uuid::from_str2(&s) {
123             println!("{:?}", u.to_string());
124         }
125     }
126 }
127