1use regex::Regex;
2use std::collections::HashMap;
3use std::process::Command;
4
5pub fn ip_regex() -> Regex {
11 Regex::new(
12 r"^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$"
13 ).unwrap()
14}
15
16pub fn public_ip_mapping() -> HashMap<String, bool> {
22 let mapping: HashMap<String, bool> = vec![
23 ("https://checkip.amazonaws.com/".to_string(), true), ("https://api.ipify.org/".to_string(), true), ("https://ipinfo.io/ip/".to_string(), true), ("https://v4.ident.me/".to_string(), true), ("https://httpbin.org/ip".to_string(), false), ("https://myip.dnsomatic.com/".to_string(), true), ]
30 .into_iter()
31 .collect();
32 mapping
33}
34
35
36pub fn convert_seconds(seconds: i64) -> String {
46 let days = seconds / 86_400; let hours = (seconds % 86_400) / 3_600; let minutes = (seconds % 3_600) / 60; let remaining_seconds = seconds % 60;
50
51 let mut result = Vec::new();
52
53 if days > 0 {
54 result.push(format!("{} day{}", days, if days > 1 { "s" } else { "" }));
55 }
56 if hours > 0 {
57 result.push(format!("{} hour{}", hours, if hours > 1 { "s" } else { "" }));
58 }
59 if minutes > 0 && result.len() < 2 {
60 result.push(format!("{} minute{}", minutes, if minutes > 1 { "s" } else { "" }));
61 }
62 if remaining_seconds > 0 && result.len() < 2 {
63 result.push(format!("{} second{}", remaining_seconds, if remaining_seconds > 1 { "s" } else { "" }));
64 }
65 result.join(" and ")
66}
67
68pub fn size_converter(byte_size: u64) -> String {
78 let size_name = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
79 let mut index = 0;
80 let mut size = byte_size as f64;
81
82 while size >= 1024.0 && index < size_name.len() - 1 {
83 size /= 1024.0;
84 index += 1;
85 }
86
87 format!("{:.2} {}", size, size_name[index])
88}
89
90pub fn run_command(command: &str, args: &[&str], log: bool) -> Result<String, String> {
101 match Command::new(command)
102 .args(args)
103 .output()
104 {
105 Ok(output) => {
106 if output.status.success() {
107 Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
108 } else {
109 let stderr = String::from_utf8_lossy(&output.stderr).to_string();
110 let exit_code = output.status.code().unwrap_or(-1);
111 if log {
112 log::error!("Command [{}] failed with exit code: {}", command, exit_code);
113 log::error!("Stderr: {}", stderr);
114 }
115 Err(stderr)
116 }
117 }
118 Err(err) => {
119 if log {
120 log::error!("Failed to execute command [{}]: {}", command, err);
121 }
122 Err(err.to_string())
123 }
124 }
125}
126
127pub fn capwords(string: &str, sep: Option<&str>) -> String {
138 let separator = sep.unwrap_or(" ");
139 let mut result = Vec::new();
140
141 for word in string.split(separator) {
142 let mut chars = word.chars();
143 if let Some(first) = chars.next() {
144 let capitalized_word = first.to_uppercase().collect::<String>() + chars.as_str();
145 result.push(capitalized_word);
146 } else {
147 result.push(String::new());
148 }
149 }
150
151 result.join(separator)
152}