cool_id_generator/
lib.rs

1/*!
2This is a cool-id-generator.
3
4It makes memorable ids.
5honest-turbo-tailor-gregory, romantic-robot-chicken-kenneth and happy-ultra-barista-shane would approve.
6
7```
8#[macro_use]
9use cool_id_generator::{get_id, Size};
10
11let my_id = get_id(Size::Medium);
12println!("{:?}", my_id);
13let my_long_id = get_id(Size::Long);
14println!("{:?}", my_long_id);
15
16```
17*/
18#![no_std]
19
20#[macro_use]
21extern crate alloc;
22use alloc::string::String;
23
24pub mod words;
25use words::{ADJECTIVES, ANIMALS, ANIMAL_PREFIX, JOBS, JOBS_PREFIX, NAMES};
26
27use rand::seq::SliceRandom;
28use rand::thread_rng;
29
30#[inline]
31pub fn get_id(size: Size) -> String {
32    let mut rng = thread_rng();
33
34    let animal_or_job = {
35        if rand::random::<bool>() {
36            (
37                ANIMAL_PREFIX.choose(&mut rng).unwrap(),
38                ANIMALS.choose(&mut rng).unwrap(),
39            )
40        } else {
41            (
42                JOBS_PREFIX.choose(&mut rng).unwrap(),
43                JOBS.choose(&mut rng).unwrap(),
44            )
45        }
46    };
47
48    match size {
49        Size::Medium => {
50            let adj1 = ADJECTIVES.choose(&mut rng).unwrap();
51            let name = NAMES.choose(&mut rng).unwrap();
52            format!("{}{}-{}-{}", adj1, animal_or_job.0, animal_or_job.1, name)
53        }
54        Size::Long => {
55            let name = NAMES.choose(&mut rng).unwrap();
56            let adj1 = ADJECTIVES.choose(&mut rng).unwrap();
57            let adj2 = ADJECTIVES.choose(&mut rng).unwrap();
58            format!(
59                "{}-the-{}-and-{}{}-{}",
60                name, adj1, adj2, animal_or_job.0, animal_or_job.1
61            )
62        }
63        Size::VeryLong => {
64            let name = NAMES.choose(&mut rng).unwrap();
65            let name2 = NAMES.choose(&mut rng).unwrap();
66            let adj1 = ADJECTIVES.choose(&mut rng).unwrap();
67            let adj2 = ADJECTIVES.choose(&mut rng).unwrap();
68            format!(
69                "{}-{}-the-{}-and-{}{}-{}",
70                name, name2, adj1, adj2, animal_or_job.0, animal_or_job.1
71            )
72        }
73    }
74}
75
76/// Size which can be cast into `usize` to use as the size of the output byte array e.g.
77/// ## Example
78/// ```
79/// use cool_id_generator::Size;
80///
81/// const size: usize = Size::Medium as usize;
82/// let byte_array: [u8; size] = [0u8; size];
83/// ```
84pub enum Size {
85    /// The largest size (in bytes) of a `Medium` ID; 1 billion combinations
86    Medium = get_id_max_len() as isize,
87    /// The largest size (in bytes) of a `Long` ID; 115 billion combinations
88    Long = get_long_id_max_len() as isize,
89    /// The largest size (in bytes) of a `VeryLong` ID; 10^15 combinations (or 2,088,136,477,473,228)
90    VeryLong = get_very_long_id_max_len() as isize,
91}
92
93const fn max(a: usize, b: usize) -> usize {
94    [a, b][(a < b) as usize]
95}
96
97// returns maximum byte lengh of the given array
98const fn get_max_len(items: &[&str]) -> usize {
99    let mut i = 0;
100    let mut largest = 0;
101    while i < items.len() {
102        let len = items[i].len();
103        if len > largest {
104            largest = len
105        };
106        i += 1;
107    }
108    largest
109}
110
111const fn get_very_long_id_max_len() -> usize {
112    max(get_max_len(&ANIMAL_PREFIX), get_max_len(&JOBS_PREFIX))
113        + get_max_len(&NAMES)
114        + get_max_len(&NAMES)
115        + get_max_len(&ADJECTIVES)
116        + get_max_len(&ADJECTIVES)
117        + get_max_len(&ANIMALS)
118        + get_max_len(&JOBS)
119}
120
121const fn get_long_id_max_len() -> usize {
122    max(get_max_len(&ANIMAL_PREFIX), get_max_len(&JOBS_PREFIX))
123        + get_max_len(&NAMES)
124        + get_max_len(&ADJECTIVES)
125        + get_max_len(&ADJECTIVES)
126        + get_max_len(&ANIMALS)
127        + get_max_len(&JOBS)
128}
129
130const fn get_id_max_len() -> usize {
131    max(get_max_len(&ANIMAL_PREFIX), get_max_len(&JOBS_PREFIX))
132        + get_max_len(&NAMES)
133        + get_max_len(&ADJECTIVES)
134        + get_max_len(&ANIMALS)
135        + get_max_len(&JOBS)
136}
137
138#[cfg(test)]
139mod tests {
140    extern crate std;
141
142    use crate::*;
143    use std::println;
144    #[test]
145    fn it_works() {
146        // let yo: Vec<String> = (0..1000).map(|_|get_id()).collect();
147        // println!("{:?}", yo.join(" "));
148
149        println!("{}", get_id(Size::Medium));
150        println!("{}", get_id(Size::Medium));
151        println!("{}", get_id(Size::Medium));
152        println!("{}", get_id(Size::Long));
153        println!("{}", get_id(Size::Long));
154        println!("{}", get_id(Size::Long));
155        println!("{}", get_id(Size::VeryLong));
156        println!("{}", get_id(Size::VeryLong));
157        println!("{}", get_id(Size::VeryLong));
158
159        println!("{}", get_id_max_len());
160        println!("{}", get_long_id_max_len());
161        println!("{}", get_very_long_id_max_len());
162    }
163}