use crate::{enums::StringBounds, utils::{pairs_to_string_bounds, strs_to_string_bounds}, StripCharacters};
pub trait SimpleMatch {
fn starts_with_ci(&self, pattern: &str) -> bool;
fn starts_with_ci_alphanum(&self, pattern: &str) -> bool;
fn ends_with_ci(&self, pattern: &str) -> bool;
fn ends_with_ci_alphanum(&self, pattern: &str) -> bool;
fn contains_ci(&self, pattern: &str) -> bool;
fn contains_ci_alphanum(&self, pattern: &str) -> bool;
}
impl SimpleMatch for str {
fn starts_with_ci(&self, pattern: &str) -> bool {
self.to_lowercase().starts_with(&pattern.to_lowercase())
}
fn starts_with_ci_alphanum(&self, pattern: &str) -> bool {
self.to_lowercase().strip_non_alphanum().starts_with(&pattern.to_lowercase())
}
fn ends_with_ci(&self, pattern: &str) -> bool {
self.to_lowercase().ends_with(&pattern.to_lowercase())
}
fn ends_with_ci_alphanum(&self, pattern: &str) -> bool {
self.to_lowercase().strip_non_alphanum().ends_with(&pattern.to_lowercase())
}
fn contains_ci(&self, pattern: &str) -> bool {
self.to_lowercase().contains(&pattern.to_lowercase())
}
fn contains_ci_alphanum(&self, pattern: &str) -> bool {
self.to_lowercase().strip_non_alphanum().contains(&pattern.to_lowercase())
}
}
pub trait MatchOccurrences {
fn find_matched_indices(&self, pat: &str) -> Vec<usize>;
}
impl MatchOccurrences for str {
fn find_matched_indices(&self, pat: &str) -> Vec<usize> {
self.match_indices(pat).into_iter().map(|pair| pair.0).collect::<Vec<usize>>()
}
}
pub trait SimpleMatchesMany where Self:SimpleMatch {
fn matched_conditional(&self, pattern_sets: &[StringBounds]) -> Vec<bool>;
fn contains_conditional(&self, pattern_sets: &[(&str, bool)]) -> Vec<bool> {
let pattern_sets: Vec<StringBounds> = pairs_to_string_bounds(pattern_sets, 2);
self.matched_conditional(&pattern_sets)
}
fn contains_conditional_ci(&self, patterns: &[&str]) -> Vec<bool> {
let pattern_sets: Vec<StringBounds> = strs_to_string_bounds(patterns, true, 2);
self.matched_conditional(&pattern_sets)
}
fn contains_conditional_cs(&self, patterns: &[&str]) -> Vec<bool> {
let pattern_sets: Vec<StringBounds> = strs_to_string_bounds(patterns, false, 2);
self.matched_conditional(&pattern_sets)
}
}
impl SimpleMatchesMany for str {
fn matched_conditional(&self, pattern_sets: &[StringBounds]) -> Vec<bool> {
let mut matched_items: Vec<bool> = Vec::with_capacity(pattern_sets.len());
for item in pattern_sets {
let ci = item.case_insensitive();
let base = if ci {
self.to_lowercase()
} else {
self.to_owned()
};
let pattern = if ci {
item.pattern().to_lowercase()
} else {
item.pattern().to_owned()
};
let is_matched = if item.starts_with() {
base.starts_with(&pattern)
} else if item.ends_with() {
base.ends_with(&pattern)
} else {
base.contains(&pattern)
} == item.is_positive();
matched_items.push(is_matched);
}
matched_items
}
}
pub trait SimpleMatchAll where Self:SimpleMatchesMany {
fn match_all_conditional(&self, pattern_sets: &[StringBounds]) -> bool;
fn contains_all_conditional(&self, pattern_sets: &[(&str, bool)]) -> bool {
let pattern_sets: Vec<StringBounds> = pairs_to_string_bounds(pattern_sets, 2);
self.match_all_conditional(&pattern_sets)
}
fn contains_all_conditional_ci(&self, patterns: &[&str]) -> bool {
let pattern_sets: Vec<StringBounds> = strs_to_string_bounds(patterns, true, 2);
self.match_all_conditional(&pattern_sets)
}
fn contains_all_conditional_cs(&self, patterns: &[&str]) -> bool {
let pattern_sets: Vec<StringBounds> = strs_to_string_bounds(patterns, false, 2);
self.match_all_conditional(&pattern_sets)
}
}
impl SimpleMatchAll for str {
fn match_all_conditional(&self, pattern_sets: &[StringBounds]) -> bool {
self.matched_conditional(pattern_sets).into_iter().all(|matched| matched)
}
}
pub trait SimpleFilterAll {
fn filter_all_conditional(&self, pattern_sets: &[StringBounds]) -> Vec<&str>;
}
impl SimpleFilterAll for [&str] {
fn filter_all_conditional(&self, pattern_sets: &[StringBounds]) -> Vec<&str> {
self.into_iter().map(|s| s.to_owned()).filter(|s| s.match_all_conditional(pattern_sets)).collect::<Vec<&str>>()
}
}
impl SimpleFilterAll for [String] {
fn filter_all_conditional(&self, pattern_sets: &[StringBounds]) -> Vec<&str> {
self.into_iter().filter(|s| s.match_all_conditional(pattern_sets)).map(|s| s.as_str()).collect::<Vec<&str>>()
}
}