warlocks_cauldron/providers/
internet.rs1use chrono::Datelike;
2pub use ipaddress::*;
3
4use super::dependencies::*;
5use super::{Datetime, File, Text};
6
7
8#[derive(Debug)]
9pub enum StockType {
10 URL(String),
11 Image(Vec<u8>),
12}
13
14pub struct Internet;
16
17impl Internet {
18 pub fn content_type(mime_type: Option<MimeType>) -> String {
25 format!("Content-Type: {}", File::mime_type(mime_type))
26 }
27
28 pub fn http_status_message() -> &'static str {
32 get_random_element(HTTP_STATUS_MSGS.iter())
33 }
34
35 pub fn http_status_code() -> &'static str {
39 get_random_element(HTTP_STATUS_CODES.iter())
40 }
41
42 pub fn http_method() -> &'static str {
46 get_random_element(HTTP_METHODS.iter())
47 }
48
49 pub fn port(port_range: Option<PortRange>) -> u16 {
56 let range = validate_enum(port_range, Some(PortRange::ALL));
57 randint(range.0, range.1)
58 }
59
60 pub fn ip_v4_object() -> IPAddress {
64 ipv4::from_u32(randint(0, 4294967295), 32).expect("Cant create v4 IPAddress!")
65 }
66
67 pub fn ip_v4() -> String {
71 Self::ip_v4_object().to_s()
72 }
73
74 pub fn ip_v4_with_port(port_range: Option<PortRange>) -> String {
81 format!("{}:{}", Self::ip_v4(), Self::port(port_range))
82 }
83
84 pub fn ip_v6_object() -> IPAddress {
88 ipv6::from_int(randbigint(u128::MIN, u128::MAX), 32).expect("Cant create v6 IPAddress!")
89 }
90
91 pub fn ip_v6() -> String {
95 Self::ip_v6_object().to_s()
96 }
97
98 pub fn mac() -> String {
102 vec![
103 0x00,
104 0x16,
105 0x3E,
106 randint(0x00, 0x7F),
107 randint(0x00, 0xFF),
108 randint(0x00, 0xFF),
109 ].iter().map(|i| format!("{:02x}", i))
110 .join(":")
111 }
112
113 pub fn emoji() -> &'static str {
117 get_random_element(EMOJI.iter())
118 }
119
120 pub fn stock_image(width: u32, height: u32, keywords: Vec<&str>, to_image: bool) -> StockType {
130 let keywords_str = keywords.join(",");
131 let url = format!("https://source.unsplash.com/{width}x{height}?{keywords_str}");
132
133 match to_image {
134 true => {
135 let r = reqwest::blocking::get(url).expect("Cant fetch images from unsplash!")
136 .bytes().expect("Cant get output!");
137
138 StockType::Image(r.to_vec())
139 },
140 false => StockType::URL(url),
141 }
142 }
143
144 pub fn hashtags(quantity: i32) -> Vec<String> {
151 let locale = Text(&Locale::EN);
152 (0..quantity).map(|_| format!("#{}", locale.word())).collect()
153 }
154
155 pub fn top_level_domain(tld_type: Option<TLDType>) -> &'static str {
162 let tld = validate_enum(tld_type, None);
163 get_random_element(TLD.get(tld).expect("Cant get TLD type!").iter())
164 }
165
166 pub fn tld(tld_type: Option<TLDType>) -> &'static str {
173 Self::top_level_domain(tld_type)
174 }
175
176 pub fn user_agent() -> &'static str {
180 get_random_element(USER_AGENTS.iter())
181 }
182
183 pub fn public_dns() -> &'static str {
187 get_random_element(PUBLIC_DNS.iter())
188 }
189
190 pub fn slug(parts_count: Option<usize>) -> String {
194 let parts = parts_count.unwrap_or_else(|| randint(2, 12));
195
196 if parts > 12 {
197 panic!("Slug's parts count must be <= 12");
198 }
199
200 if parts < 2 {
201 panic!("Slug must contain more than 2 parts");
202 }
203
204 Text(&Locale::EN).words(parts).iter().join("-")
205 }
206
207 pub fn hostname(tld_type: Option<TLDType>, subdomains: Option<Vec<&str>>) -> String {
215 let tld = Self::top_level_domain(tld_type);
216 let host = get_random_element(USERNAMES.iter());
217
218 let mut url = format!("{host}{tld}");
219
220 if let Some(v) = subdomains {
221 url = format!("{}.{url}", get_random_element(v.iter()));
222 }
223
224 url
225 }
226
227 pub fn url(scheme: Option<URLScheme>, port_range: Option<PortRange>, tld_type: Option<TLDType>, subdomains: Option<Vec<&str>>) -> String {
237 let hostname = Self::hostname(tld_type, subdomains);
238 let scheme = validate_enum(scheme, None);
239 let mut url = format!("{scheme}://{hostname}");
240
241 if port_range.is_some() {
242 url = format!("{url}:{}", Self::port(port_range));
243 }
244
245 format!("{url}/")
246 }
247
248 pub fn uri(scheme: Option<URLScheme>, port_range: Option<PortRange>, tld_type: Option<TLDType>, subdomains: Option<Vec<&str>>, query_params_count: Option<usize>) -> String {
259 let directory = Datetime::date(2010, chrono::Local::now().year()).format("%Y/%m/%d");
260
261 let mut url = format!("{}{directory}/{}", Self::url(scheme, port_range, tld_type, subdomains), Self::slug(None));
262
263 if query_params_count.is_some() {
264 url = format!("{url}?{}", Self::query_string(query_params_count));
265 }
266
267 url
268 }
269
270 pub fn query_string(length: Option<usize>) -> String {
277 let formated = Self::query_parameters(length).iter().map(|p| {
278 format!("{}={}", p.0, p.1)
279 }).join("&");
280
281 urlencoding::encode(&formated).into_owned()
282 }
283
284 pub fn query_parameters(length: Option<usize>) -> Vec<(&'static str, &'static String)> {
291 let text = &Text(&Locale::RU);
292 let length = length.unwrap_or_else(|| randint(1, 10));
293
294 if length > 32 {
295 panic!("Length should be less than 32!")
296 }
297
298 let mut unique_words: Vec<&'static str> = vec![];
299 while unique_words.len() < length {
300 let word = text.word();
301 if !unique_words.contains(&word) {
302 unique_words.push(word)
303 }
304 }
305
306 unique_words.into_iter().zip(text.words(length)).collect()
307 }
308}