bharat_cafe/
lib.rs

1use once_cell::sync::Lazy;
2use rand::seq::SliceRandom;
3use rand::thread_rng;
4use rand::Rng;
5use std::sync::Mutex;
6
7// These are now loaded from files at compile time.
8static FIRST_NAMES: Lazy<Vec<&str>> = Lazy::new(|| {
9    include_str!("../data/firstnames.txt")
10        .lines()
11        .collect::<Vec<&str>>()
12});
13static LAST_NAMES: Lazy<Vec<&str>> = Lazy::new(|| {
14    include_str!("../data/lastnames.txt")
15        .lines()
16        .collect::<Vec<&str>>()
17});
18
19pub static CITIES: Lazy<Vec<&str>> = Lazy::new(|| {
20    include_str!("../data/cities.txt")
21        .lines()
22        .collect::<Vec<&str>>()
23});
24pub static STATES: Lazy<Vec<&str>> = Lazy::new(|| {
25    include_str!("../data/states.txt")
26        .lines()
27        .collect::<Vec<&str>>()
28});
29pub static STREETS: Lazy<Vec<&str>> = Lazy::new(|| {
30    include_str!("../data/streets.txt")
31        .lines()
32        .collect::<Vec<&str>>()
33});
34
35static COMPANY_SUFFIX: Lazy<Vec<&'static str>> = Lazy::new(|| {
36    vec![
37        "Technologies",
38        "Industries",
39        "& Sons",
40        "Pvt Ltd.",
41        "Solutions",
42        "Services",
43        "Systems",
44        "& Co.",
45        "Enterprises",
46        "Distributors",
47        "Ceramics Ltd",
48        "Electronics",
49        "Hotels Group",
50        "Studios Ltd",
51        "Corporation",
52        "Innovations",
53        "Pharmaceuticals",
54        "Realtors",
55        "Automobiles",
56        "Instruments",
57        "Airlines",
58        "Holdings",
59        "Ventures",
60        "Equipments Ltd",
61        "Pharma",
62        "Cosmetics Ltd",
63        "Publishers",
64        "Technologies Pvt Ltd",
65        "Microdevices",
66        "Biotech",
67        "Micro Systems Ltd",
68        "Software",
69        // Add more suffixes here
70    ]
71});
72
73static COMPANY_PREFIX: Lazy<Vec<&'static str>> = Lazy::new(|| {
74    include_str!("../data/firstnames.txt")
75        .lines()
76        .collect::<Vec<_>>()
77});
78
79pub fn random_name() -> String {
80    let mut rng = thread_rng();
81    let first_name = FIRST_NAMES.choose(&mut rng).unwrap();
82    let last_name = LAST_NAMES.choose(&mut rng).unwrap();
83    format!("{} {}", first_name, last_name)
84}
85
86pub fn random_phone() -> String {
87    let mut rng = thread_rng();
88    let first_digit: u8 = rng.gen_range(7..=9);
89    let remaining_digits: u64 = rng.gen_range(100000000..=999999999);
90    format!("{}{}", first_digit, remaining_digits)
91}
92
93pub fn random_address() -> String {
94    let mut rng = thread_rng();
95    let city = CITIES.choose(&mut rng).unwrap();
96    let state = STATES.choose(&mut rng).unwrap();
97    let street = STREETS.choose(&mut rng).unwrap();
98    let house_number: u32 = rng.gen_range(1..9999);
99    format!("{} {}, {}, {}", house_number, street, city, state)
100}
101
102static EMAIL_DOMAINS: Lazy<Vec<&str>> = Lazy::new(|| {
103    vec![
104        "xmail.com",
105        "zahoo.com",
106        "potmail.com",
107        "scoutlook.com",
108        "krotonmail.com",
109    ]
110});
111
112static ALL_NAMES: Lazy<Mutex<Vec<String>>> = Lazy::new(|| {
113    let mut all_names = Vec::new();
114    for prefix in &*COMPANY_PREFIX {
115        for suffix in &*COMPANY_SUFFIX {
116            all_names.push(format!("{} {}", prefix, suffix));
117        }
118    }
119    let mut rng = rand::thread_rng();
120    all_names.shuffle(&mut rng);
121    Mutex::new(all_names)
122});
123
124pub fn random_email(domain_name: Option<&str>) -> String {
125    let mut rng = thread_rng();
126    let first_name = FIRST_NAMES.choose(&mut rng).unwrap().to_lowercase();
127    let last_name = LAST_NAMES.choose(&mut rng).unwrap().to_lowercase();
128    let domain = domain_name.unwrap_or_else(|| EMAIL_DOMAINS.choose(&mut rng).unwrap());
129    format!("{}.{}@{}", first_name, last_name, domain)
130}
131
132pub fn random_email_from_name(name: &str, domain_name: Option<&str>) -> String {
133    let mut rng = thread_rng();
134    let domain = domain_name.unwrap_or_else(|| EMAIL_DOMAINS.choose(&mut rng).unwrap());
135    let name_part: String = name
136        .split_whitespace()
137        .map(|s| s.to_lowercase())
138        .collect::<Vec<_>>()
139        .join(".");
140    format!("{}@{}", name_part, domain)
141}
142
143pub fn generate_company_name() -> String {
144    let mut all_names = ALL_NAMES.lock().unwrap();
145    if all_names.is_empty() {
146        for prefix in &*COMPANY_PREFIX {
147            for suffix in &*COMPANY_SUFFIX {
148                all_names.push(format!("{} {}", prefix, suffix));
149            }
150        }
151        let mut rng = rand::thread_rng();
152        all_names.shuffle(&mut rng);
153    }
154    all_names.pop().expect("Failed to generate a company name")
155}
156
157#[cfg(test)]
158mod tests {
159    use super::*;
160    use std::collections::HashSet;
161
162    #[test]
163    fn test_generate_name() {
164        let name = random_name();
165        assert!(!name.is_empty(), "Generated name should not be empty");
166
167        let parts: Vec<&str> = name.split_whitespace().collect();
168        assert_eq!(parts.len(), 2, "Generated name should have two parts");
169
170        assert!(
171            FIRST_NAMES.contains(&parts[0]),
172            "First name should be in the list of first names"
173        );
174        assert!(
175            LAST_NAMES.contains(&parts[1]),
176            "Last name should be in the list of last names"
177        );
178    }
179
180    #[test]
181    fn test_generate_names_in_loop() {
182        let mut generated_names = HashSet::new();
183
184        for _ in 0..108 {
185            let name = random_name();
186            //println!("Generated name: {}", name); // Print the generated name
187            assert!(!name.is_empty(), "Generated name should not be empty");
188
189            let parts: Vec<&str> = name.split_whitespace().collect();
190            assert_eq!(parts.len(), 2, "Generated name should have two parts");
191
192            assert!(
193                FIRST_NAMES.contains(&parts[0]),
194                "First name should be in the list of first names"
195            );
196            assert!(
197                LAST_NAMES.contains(&parts[1]),
198                "Last name should be in the list of last names"
199            );
200
201            // Check that the name has not been generated before
202            assert!(
203                generated_names.insert(name),
204                "Generated name should be unique"
205            );
206        }
207    }
208
209    #[test]
210    fn test_generate_phone() {
211        let phone = random_phone();
212        //println!("Generated phone: {}", phone); // Print the generated phone
213        assert_eq!(phone.len(), 10, "Phone number should have 10 digits");
214    }
215
216    #[test]
217    fn test_generate_unique_addresses() {
218        let mut generated_addresses = HashSet::new();
219
220        for _ in 0..1000 {
221            let address = random_address();
222            assert!(!address.is_empty(), "Generated address should not be empty");
223
224            // Check that the address has not been generated before
225            assert!(
226                generated_addresses.insert(address),
227                "Generated address should be unique"
228            );
229        }
230    }
231
232    #[test]
233    fn test_unique_emails() {
234        let mut rng = rand::thread_rng();
235        let domains = vec!["example.com", "test.com", "domain.com"];
236        let mut emails = HashSet::new();
237        for _ in 0..1000 {
238            let email = if rng.gen_bool(0.5) {
239                random_email(None)
240            } else {
241                let domain = domains.choose(&mut rng).unwrap();
242                random_email(Some(domain))
243            };
244            emails.insert(email);
245        }
246        //println!("Emails count: {:?}", emails.len()); // Print the generated email count
247        assert_eq!(emails.len(), 1000);
248    }
249
250    #[test]
251    fn test_unique_company_names() {
252        let mut company_names = HashSet::new();
253        for _ in 0..1000 {
254            let name = generate_company_name();
255            println!("Generated company name: {}", name); // Print the generated company name
256            assert!(
257                company_names.insert(name),
258                "Duplicate company name generated"
259            );
260        }
261    }
262
263    #[test]
264    fn test_random_email_from_name() {
265        let email = random_email_from_name("Ravi Kumar", None);
266        assert!(email.starts_with("ravi.kumar@"));
267
268        let email_with_domain = random_email_from_name("Priya Sharma", Some("company.com"));
269        assert_eq!(email_with_domain, "priya.sharma@company.com");
270
271        let single_name = random_email_from_name("Arjun", Some("test.com"));
272        assert_eq!(single_name, "arjun@test.com");
273    }
274}