ft_sdk/
uuid.rs

1// Reference - https://github.com/tmtmtoo/uuid-v4-wasm/blob/develop/src/uuid.rs
2// License - MIT (https://github.com/tmtmtoo/uuid-v4-wasm/blob/develop/LICENSE)
3
4enum UuidElements {
5    Random09AF,
6    Random89AB,
7    Hyphen,
8    Version,
9}
10
11const UUID_V4_FORMAT: [UuidElements; 36] = [
12    UuidElements::Random09AF,
13    UuidElements::Random09AF,
14    UuidElements::Random09AF,
15    UuidElements::Random09AF,
16    UuidElements::Random09AF,
17    UuidElements::Random09AF,
18    UuidElements::Random09AF,
19    UuidElements::Random09AF,
20    UuidElements::Hyphen,
21    UuidElements::Random09AF,
22    UuidElements::Random09AF,
23    UuidElements::Random09AF,
24    UuidElements::Random09AF,
25    UuidElements::Hyphen,
26    UuidElements::Version,
27    UuidElements::Random09AF,
28    UuidElements::Random09AF,
29    UuidElements::Random09AF,
30    UuidElements::Hyphen,
31    UuidElements::Random89AB,
32    UuidElements::Random09AF,
33    UuidElements::Random09AF,
34    UuidElements::Random09AF,
35    UuidElements::Hyphen,
36    UuidElements::Random09AF,
37    UuidElements::Random09AF,
38    UuidElements::Random09AF,
39    UuidElements::Random09AF,
40    UuidElements::Random09AF,
41    UuidElements::Random09AF,
42    UuidElements::Random09AF,
43    UuidElements::Random09AF,
44    UuidElements::Random09AF,
45    UuidElements::Random09AF,
46    UuidElements::Random09AF,
47    UuidElements::Random09AF,
48];
49
50const ERROR_MAKE_CHAR: &str = "Error in making char";
51
52fn make_bytes(value: f64) -> [u8; 16] {
53    let bytes = value.to_bits();
54
55    let b1: u8 = ((bytes >> 56) & 0xff) as u8;
56    let b2: u8 = ((bytes >> 48) & 0xff) as u8;
57    let b3: u8 = ((bytes >> 40) & 0xff) as u8;
58    let b4: u8 = ((bytes >> 36) & 0xff) as u8;
59    let b5: u8 = ((bytes >> 24) & 0xff) as u8;
60    let b6: u8 = ((bytes >> 16) & 0xff) as u8;
61    let b7: u8 = ((bytes >> 8) & 0xff) as u8;
62    let b8: u8 = (bytes & 0xff) as u8;
63
64    [
65        b8, b7, b6, b5, b4, b3, b2, b1, b1, b2, b3, b4, b5, b6, b7, b8,
66    ]
67}
68
69/// generate UUID with XorShift algorithm
70pub fn uuid() -> String {
71    use rand::{Rng, SeedableRng};
72
73    let seed = ft_sdk::env::random();
74
75    let bytes = make_bytes(seed);
76    let mut rng = rand::XorShiftRng::from_seed(bytes);
77
78    // prevent duplication
79    rng.gen_range(0., 1.);
80
81    UUID_V4_FORMAT
82        .into_iter()
83        .map(|n| match n {
84            UuidElements::Random09AF => {
85                let random = rng.gen_range(0., 1.);
86                char::from_digit((random * 16.) as u32, 16).expect(ERROR_MAKE_CHAR)
87            }
88            UuidElements::Random89AB => {
89                let random = rng.gen_range(0., 1.);
90                char::from_digit((random * 4.) as u32 + 8, 16).expect(ERROR_MAKE_CHAR)
91            }
92            UuidElements::Version => '4',
93            UuidElements::Hyphen => '-',
94        })
95        .collect()
96}
97
98/// Generate UUID without dashes, this is useful for URLs, as one can click Alt-Backspace and
99/// delete the whole UUID. In the of regular UUID, it will delete only one part of it, and one
100/// has to press backspace multiple times to delete the whole UUID, which is annoying.
101pub fn uuid_without_dashes() -> String {
102    uuid().replace("-", "")
103}