1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
///all utils functions, activate feature by `cargo add doe -F utils`
#[cfg(feature = "utils")]
#[allow(warnings)]
pub mod utils {
    ///The Vec sort all elements can be repeated to define the longest shortest size
    /// ```ignore
    ///fn main() {
    ///     use doe::DebugPrint;
    ///     use doe::utils::generate_all_possible_vec;
    ///    let v  = generate_all_possible_vec(&vec![1,2,3],1,2);
    ///    v.dprintln();//[[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2], [3, 3]]
    ///}
    ///```
    pub fn generate_all_possible_vec<T: Clone>(
        elements: &[T],
        min_len: usize,
        max_len: usize,
    ) -> Vec<Vec<T>> {
        let mut result = Vec::new();
        for len in min_len..=max_len {
            let mut indices = vec![0; len];
            let mut done = false;
            while !done {
                let permutation = indices.iter().map(|&i| elements[i].clone()).collect();
                result.push(permutation);
                done = true;
                for i in (0..len).rev() {
                    indices[i] += 1;
                    if indices[i] == elements.len() {
                        indices[i] = 0;
                    } else {
                        done = false;
                        break;
                    }
                }
            }
        }
        result
    }
    ///permutations
    /// ```ignore
    ///fn main() {
    ///    use doe::utils::permutations;
    ///    use doe::DebugPrint;
    ///    permutations("abc").dprintln();//["abc", "acb", "bac", "bca", "cba", "cab"]
    ///}
    /// ```
    pub fn permutations(alphabet: &str) -> Vec<String> {
        fn permute(chars: &mut [char], start: usize, result: &mut Vec<String>) {
            if start == chars.len() {
                result.push(chars.iter().collect());
            } else {
                for i in start..chars.len() {
                    chars.swap(start, i);
                    permute(chars, start + 1, result);
                    chars.swap(start, i);
                }
            }
        }

        let mut result = Vec::new();
        let mut chars: Vec<char> = alphabet.chars().collect();
        permute(&mut chars, 0, &mut result);
        result
    }

    use std::sync::{Arc, Mutex};

    pub fn hex_encode(s: impl ToString) -> impl ToString {
        hex::encode(s.to_string())
    }

    pub fn hex_decode(s: impl ToString) -> impl ToString {
        String::from_utf8_lossy(&hex::decode(s.to_string()).unwrap()).to_string()
    }

    pub fn base64_encode(s: impl ToString) -> String {
        use base64::{engine::general_purpose, Engine as _};
        general_purpose::STANDARD_NO_PAD.encode(s.to_string())
    }
    pub fn base64_decode(s: impl ToString) -> String {
        use base64::{engine::general_purpose, Engine as _};
        let decode_s_vec = general_purpose::STANDARD_NO_PAD
            .decode(s.to_string())
            .unwrap();
        String::from_utf8_lossy(&decode_s_vec).to_string()
    }

    pub fn all_lowercase_letters() -> Arc<str> {
        Arc::from("abcdefghijklmnopqrstuvwxyz")
    }
    pub fn all_uppercase_letters() -> Arc<str> {
        Arc::from("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    }

    pub fn all_digits() -> Arc<str> {
        Arc::from("0123456789")
    }

    pub fn all_letters_and_digits() -> Arc<str> {
        Arc::from(
            format!(
                "{}{}{}",
                all_lowercase_letters(),
                all_uppercase_letters(),
                all_digits()
            )
            .as_ref(),
        )
    }

    pub fn php_urlencode(url: &str) -> String {
        use percent_encoding::{percent_decode_str, utf8_percent_encode};
        let encoded = utf8_percent_encode(url, percent_encoding::NON_ALPHANUMERIC);
        encoded.to_string()
    }
    pub fn php_urldecode(url: &str) -> String {
        use percent_encoding::{percent_decode_str, utf8_percent_encode};
        let decoded = percent_decode_str(url).decode_utf8().unwrap();
        decoded.to_string()
    }
}