use regex::Regex;
use std::collections::HashSet;
#[derive(Debug, Default, Clone)]
pub enum ContractFilter {
#[default]
All,
Select(SelectContracts),
Exclude(ExcludeContracts),
}
impl ContractFilter {
pub fn is_match(&self, name: impl AsRef<str>) -> bool {
match self {
ContractFilter::All => true,
ContractFilter::Select(f) => f.is_match(name),
ContractFilter::Exclude(f) => !f.is_match(name),
}
}
}
impl From<SelectContracts> for ContractFilter {
fn from(f: SelectContracts) -> Self {
ContractFilter::Select(f)
}
}
impl From<ExcludeContracts> for ContractFilter {
fn from(f: ExcludeContracts) -> Self {
ContractFilter::Exclude(f)
}
}
macro_rules! impl_filter {
($name:ident) => {
impl $name {
pub fn add_name<T: Into<String>>(mut self, arg: T) -> Self {
self.exact.insert(arg.into());
self
}
pub fn extend_names<I, S>(mut self, name: I) -> Self
where
I: IntoIterator<Item = S>,
S: Into<String>,
{
for arg in name {
self = self.add_name(arg);
}
self
}
pub fn add_regex(mut self, re: Regex) -> Self {
self.patterns.push(re);
self
}
pub fn extend_regex<I, S>(mut self, regexes: I) -> Self
where
I: IntoIterator<Item = S>,
S: Into<Regex>,
{
for re in regexes {
self = self.add_regex(re.into());
}
self
}
pub fn add_pattern(self, pattern: impl AsRef<str>) -> Self {
self.try_add_pattern(pattern).unwrap()
}
pub fn try_add_pattern(mut self, s: impl AsRef<str>) -> Result<Self, regex::Error> {
self.patterns.push(Regex::new(s.as_ref())?);
Ok(self)
}
pub fn extend_pattern<I, S>(self, patterns: I) -> Self
where
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
self.try_extend_pattern(patterns).unwrap()
}
pub fn try_extend_pattern<I, S>(mut self, patterns: I) -> Result<Self, regex::Error>
where
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
for p in patterns {
self = self.try_add_pattern(p)?;
}
Ok(self)
}
pub fn is_match(&self, name: impl AsRef<str>) -> bool {
let name = name.as_ref();
if self.exact.contains(name) {
return true
}
self.patterns.iter().any(|re| re.is_match(name))
}
}
};
}
#[derive(Debug, Clone, Default)]
pub struct SelectContracts {
exact: HashSet<String>,
patterns: Vec<Regex>,
}
#[derive(Debug, Clone, Default)]
pub struct ExcludeContracts {
exact: HashSet<String>,
patterns: Vec<Regex>,
}
impl_filter!(SelectContracts);
impl_filter!(ExcludeContracts);