use std::{collections::HashSet, iter};
use itertools::Itertools;
use regex::{Error, Regex, RegexBuilder, RegexSet, RegexSetBuilder};
pub trait ToRegex {
fn to_regex(&self) -> Result<Regex, Error>;
}
impl ToRegex for Regex {
fn to_regex(&self) -> Result<Regex, Error> {
Ok(self.clone())
}
}
impl ToRegex for &Regex {
fn to_regex(&self) -> Result<Regex, Error> {
Ok((*self).clone())
}
}
impl ToRegex for RegexBuilder {
fn to_regex(&self) -> Result<Regex, Error> {
self.build()
}
}
impl ToRegex for &RegexBuilder {
fn to_regex(&self) -> Result<Regex, Error> {
self.build()
}
}
impl ToRegex for String {
fn to_regex(&self) -> Result<Regex, Error> {
Regex::new(self)
}
}
impl ToRegex for &String {
fn to_regex(&self) -> Result<Regex, Error> {
Regex::new(self)
}
}
impl ToRegex for &str {
fn to_regex(&self) -> Result<Regex, Error> {
Regex::new(self)
}
}
pub trait ToRegexSet {
fn to_regex_set(&self) -> Result<RegexSet, Error>;
}
impl ToRegexSet for RegexSet {
fn to_regex_set(&self) -> Result<RegexSet, Error> {
Ok(self.clone())
}
}
impl ToRegexSet for &RegexSet {
fn to_regex_set(&self) -> Result<RegexSet, Error> {
Ok((*self).clone())
}
}
impl ToRegexSet for RegexSetBuilder {
fn to_regex_set(&self) -> Result<RegexSet, Error> {
self.build()
}
}
impl ToRegexSet for &RegexSetBuilder {
fn to_regex_set(&self) -> Result<RegexSet, Error> {
self.build()
}
}
impl<T> ToRegexSet for T
where
T: ToRegex,
{
fn to_regex_set(&self) -> Result<RegexSet, Error> {
let regex = self.to_regex()?;
let regex = regex.as_str();
RegexSet::new(iter::once(regex))
}
}
pub trait CollectRegexSet {
fn collect_regex_set(self) -> Result<RegexSet, Error>;
}
impl<I> CollectRegexSet for I
where
I: IntoIterator,
I::Item: ToRegexSet,
{
fn collect_regex_set(self) -> Result<RegexSet, Error> {
let regexes: Result<Vec<RegexSet>, Error> = self
.into_iter()
.map(|item| item.to_regex_set())
.try_collect();
let regexes = regexes?;
let regexes = regexes.iter().flat_map(|regex_set| regex_set.patterns());
RegexSet::new(regexes)
}
}
pub trait RegexSetExt {
fn patterns_for_indexes(&self, indexes: &HashSet<usize>) -> Vec<String>;
}
impl RegexSetExt for RegexSet {
fn patterns_for_indexes(&self, indexes: &HashSet<usize>) -> Vec<String> {
self.patterns()
.iter()
.enumerate()
.filter(|(index, _regex)| indexes.contains(index))
.map(|(_index, regex)| regex.to_string())
.collect()
}
}