use serde::{
Deserialize,
Deserializer,
Serialize,
Serializer,
de,
};
use super::filter_expr::FilterExpr;
use super::metadata_filter_builder::MetadataFilterBuilder;
use super::wire::MetadataFilterWire;
use crate::metadata::Metadata;
use crate::{
Condition,
FilterMatchOptions,
MetadataResult,
MissingKeyPolicy,
NumberComparisonPolicy,
};
#[derive(Debug, Clone, PartialEq, Default)]
pub struct MetadataFilter {
pub(crate) expr: Option<FilterExpr>,
pub(crate) options: FilterMatchOptions,
}
impl MetadataFilter {
#[inline]
pub(crate) fn new(expr: Option<FilterExpr>, options: FilterMatchOptions) -> Self {
Self { expr, options }
}
#[inline]
#[must_use]
pub fn builder() -> MetadataFilterBuilder {
MetadataFilterBuilder::default()
}
#[inline]
#[must_use]
pub fn all() -> Self {
Self::default()
}
#[inline]
#[must_use]
pub fn none() -> Self {
Self {
expr: Some(FilterExpr::False),
options: FilterMatchOptions::default(),
}
}
#[inline]
#[must_use]
pub fn options(&self) -> FilterMatchOptions {
self.options
}
#[inline]
#[must_use]
pub fn with_options(mut self, options: FilterMatchOptions) -> Self {
self.options = options;
self
}
#[inline]
#[must_use]
pub fn with_missing_key_policy(mut self, missing_key_policy: MissingKeyPolicy) -> Self {
self.options.missing_key_policy = missing_key_policy;
self
}
#[inline]
#[must_use]
pub fn with_number_comparison_policy(
mut self,
number_comparison_policy: NumberComparisonPolicy,
) -> Self {
self.options.number_comparison_policy = number_comparison_policy;
self
}
#[allow(clippy::should_implement_trait)]
#[inline]
#[must_use]
pub fn not(mut self) -> Self {
self.expr = MetadataFilterBuilder::negate_expr(self.expr);
self
}
#[inline]
#[must_use]
pub fn matches(&self, meta: &Metadata) -> bool {
self.matches_with_options(meta, self.options)
}
#[inline]
#[must_use]
pub fn matches_with_options(&self, meta: &Metadata, options: FilterMatchOptions) -> bool {
self.expr
.as_ref()
.is_none_or(|expr| expr.matches(meta, options))
}
pub(crate) fn visit_conditions<F>(&self, mut visitor: F) -> MetadataResult<()>
where
F: FnMut(&Condition) -> MetadataResult<()>,
{
if let Some(expr) = &self.expr {
expr.visit_conditions(&mut visitor)?;
}
Ok(())
}
}
impl Serialize for MetadataFilter {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
MetadataFilterWire::from(self).serialize(serializer)
}
}
impl<'de> Deserialize<'de> for MetadataFilter {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
MetadataFilterWire::deserialize(deserializer)?
.into_filter()
.map_err(de::Error::custom)
}
}
impl std::ops::Not for MetadataFilter {
type Output = MetadataFilter;
#[inline]
fn not(self) -> Self::Output {
MetadataFilter::not(self)
}
}