Create interrelate macro to evaluate filters

This reduces code duplication.
This commit is contained in:
finga 2021-11-19 11:04:11 +01:00
parent b8f114900b
commit b7ad590d39

View file

@ -120,6 +120,30 @@ impl JsonFilter {
} }
} }
macro_rules! interrelate {
($request:expr, $data:expr, $filters:expr, $relation:ident) => {{
let (mut results, mut errors) = (Vec::new(), Vec::new());
$filters
.iter()
.map(|filter| filter.evaluate($request, $data))
.for_each(|item| match item {
Ok(o) => results.push(o),
Err(e) => errors.push(e),
});
if errors.is_empty() {
Ok(results.iter().$relation(|r| *r))
} else {
errors
.iter()
.for_each(|e| error!("Could not evaluate Filter: {}", e));
Err(WebhookeyError::InvalidFilter)
}
}};
}
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields, rename_all = "lowercase")] #[serde(deny_unknown_fields, rename_all = "lowercase")]
pub enum FilterType { pub enum FilterType {
@ -140,48 +164,8 @@ impl FilterType {
) -> Result<bool, WebhookeyError> { ) -> Result<bool, WebhookeyError> {
match self { match self {
FilterType::Not(filter) => Ok(!filter.evaluate(request, data)?), FilterType::Not(filter) => Ok(!filter.evaluate(request, data)?),
FilterType::And(filters) => { FilterType::And(filters) => interrelate!(request, data, filters, all),
let (mut results, mut errors) = (Vec::new(), Vec::new()); FilterType::Or(filters) => interrelate!(request, data, filters, any),
filters
.iter()
.map(|filter| filter.evaluate(request, data))
.for_each(|item| match item {
Ok(o) => results.push(o),
Err(e) => errors.push(e),
});
if errors.is_empty() {
Ok(results.iter().all(|r| *r))
} else {
errors
.iter()
.for_each(|e| error!("Could not evaluate Filter: {}", e));
Err(WebhookeyError::InvalidFilter)
}
}
FilterType::Or(filters) => {
let (mut results, mut errors) = (Vec::new(), Vec::new());
filters
.iter()
.map(|filter| filter.evaluate(request, data))
.for_each(|item| match item {
Ok(o) => results.push(o),
Err(e) => errors.push(e),
});
if errors.is_empty() {
Ok(results.iter().any(|r| *r))
} else {
errors
.iter()
.for_each(|e| error!("Could not evaluate Filter: {}", e));
Err(WebhookeyError::InvalidFilter)
}
}
FilterType::HeaderFilter(filter) => filter.evaluate(request.headers()), FilterType::HeaderFilter(filter) => filter.evaluate(request.headers()),
FilterType::JsonFilter(filter) => filter.evaluate(data), FilterType::JsonFilter(filter) => filter.evaluate(data),
} }