use once_cell::sync::Lazy;
pub use regex::*;
pub static REGEX_ACTIVE_CODE: &'static str = r"^[A-Za-z0-9-]{29}$";
pub static REGEX_IPV4: &'static str = r"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$";
pub static REGEX_URL: &'static str = r"^(https?://)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*/?$";
pub static REGEX_EMAIL: &'static str = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$";
pub static REGEX_MAC: &'static str =
r"[0-9A-Fa-f]{2}-[0-9A-Fa-f]{2}-[0-9A-Fa-f]{2}-[0-9A-Fa-f]{2}-[0-9A-Fa-f]{2}-[0-9A-Fa-f]{2}";
pub static REGEX_FORMAT_PATTERN: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"\{([a-zA-Z0-9_]+)\}").expect("Invalid regex pattern for REGEX_FORMAT_PATTERN")
});
#[cfg(target_os = "windows")]
pub static REGEX_ENV_PATTERN: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"\%([a-zA-Z0-9_]+)\%")
.expect("Invalid regex pattern for REGEX_ENV_PATTERN on Windows")
});
#[cfg(any(target_os = "linux", target_os = "macos"))]
pub static REGEX_ENV_PATTERN: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"\$\{([a-zA-Z0-9_]+)\}")
.expect("Invalid regex pattern for REGEX_ENV_PATTERN on Unix-like systems")
});
#[cfg(not(any(target_os = "linux", target_os = "windows", target_os = "macos")))]
pub static REGEX_ENV_PATTERN: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"\$([a-zA-Z0-9_]+)")
.expect("Invalid regex pattern for REGEX_ENV_PATTERN on other systems")
});
fn wildcard_to_regex_for_path(pattern: &str) -> Result<Regex, regex::Error> {
let mut regex_pattern = String::new();
let main_separator = std::path::MAIN_SEPARATOR.to_string();
let mut chars = pattern.chars().peekable();
while let Some(c) = chars.next() {
match c {
'*' => regex_pattern.push_str(&format!(r"([^{}]*?)", regex::escape(&main_separator))),
'?' => regex_pattern.push('.'),
'.' | '$' | '^' | '+' | '|' | '[' | ']' | '(' | ')' | '\\' => {
regex_pattern.push_str(®ex::escape(&c.to_string()));
}
_ => regex_pattern.push(c),
}
}
Regex::new(®ex_pattern)
}
pub fn regex2(input: &str, pattern: &str) -> bool {
wildcard_to_regex_for_path(pattern)
.and_then(|x| Ok(x.is_match(input)))
.unwrap_or(false)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_matches_path_pattern() {
assert!(regex2("C:/test/example.txt", "*.txt"));
assert!(regex2("D:\\1hello2.json", "1*2.json"));
assert!(regex2("test.txt", "*est.txt"));
assert!(!regex2("test.txt", "est.txt"));
assert!(!regex2("no_match", "*.txt"));
}
}