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