1use once_cell::sync::Lazy;
2use rand::seq::SliceRandom;
3use rand::thread_rng;
4use rand::Rng;
5use std::sync::Mutex;
6
7static 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 ]
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 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 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 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 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 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); 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}