qubit_metadata/filter/
metadata_filter.rs1use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
12
13use super::filter_expr::FilterExpr;
14use super::metadata_filter_builder::MetadataFilterBuilder;
15use super::wire::MetadataFilterWire;
16use crate::metadata::Metadata;
17use crate::{
18 Condition, FilterMatchOptions, MetadataResult, MissingKeyPolicy, NumberComparisonPolicy,
19};
20
21#[derive(Debug, Clone, PartialEq, Default)]
27pub struct MetadataFilter {
28 pub(crate) expr: Option<FilterExpr>,
30 pub(crate) options: FilterMatchOptions,
32}
33
34impl MetadataFilter {
35 #[inline]
37 pub(crate) fn new(expr: Option<FilterExpr>, options: FilterMatchOptions) -> Self {
38 Self { expr, options }
39 }
40
41 #[inline]
43 #[must_use]
44 pub fn builder() -> MetadataFilterBuilder {
45 MetadataFilterBuilder::default()
46 }
47
48 #[inline]
50 #[must_use]
51 pub fn all() -> Self {
52 Self::default()
53 }
54
55 #[inline]
57 #[must_use]
58 pub fn none() -> Self {
59 Self {
60 expr: Some(FilterExpr::False),
61 options: FilterMatchOptions::default(),
62 }
63 }
64
65 #[inline]
67 #[must_use]
68 pub fn options(&self) -> FilterMatchOptions {
69 self.options
70 }
71
72 #[inline]
74 #[must_use]
75 pub fn with_options(mut self, options: FilterMatchOptions) -> Self {
76 self.options = options;
77 self
78 }
79
80 #[inline]
82 #[must_use]
83 pub fn with_missing_key_policy(mut self, missing_key_policy: MissingKeyPolicy) -> Self {
84 self.options.missing_key_policy = missing_key_policy;
85 self
86 }
87
88 #[inline]
90 #[must_use]
91 pub fn with_number_comparison_policy(
92 mut self,
93 number_comparison_policy: NumberComparisonPolicy,
94 ) -> Self {
95 self.options.number_comparison_policy = number_comparison_policy;
96 self
97 }
98
99 #[allow(clippy::should_implement_trait)]
101 #[inline]
102 #[must_use]
103 pub fn not(mut self) -> Self {
104 self.expr = MetadataFilterBuilder::negate_expr(self.expr);
105 self
106 }
107
108 #[inline]
110 #[must_use]
111 pub fn matches(&self, meta: &Metadata) -> bool {
112 self.matches_with_options(meta, self.options)
113 }
114
115 #[inline]
117 #[must_use]
118 pub fn matches_with_options(&self, meta: &Metadata, options: FilterMatchOptions) -> bool {
119 self.expr
120 .as_ref()
121 .is_none_or(|expr| expr.matches(meta, options))
122 }
123
124 pub(crate) fn visit_conditions<F>(&self, mut visitor: F) -> MetadataResult<()>
126 where
127 F: FnMut(&Condition) -> MetadataResult<()>,
128 {
129 if let Some(expr) = &self.expr {
130 expr.visit_conditions(&mut visitor)?;
131 }
132 Ok(())
133 }
134}
135
136impl Serialize for MetadataFilter {
137 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
138 where
139 S: Serializer,
140 {
141 MetadataFilterWire::from(self).serialize(serializer)
142 }
143}
144
145impl<'de> Deserialize<'de> for MetadataFilter {
146 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
147 where
148 D: Deserializer<'de>,
149 {
150 MetadataFilterWire::deserialize(deserializer)?
151 .into_filter()
152 .map_err(de::Error::custom)
153 }
154}
155
156impl std::ops::Not for MetadataFilter {
157 type Output = MetadataFilter;
158
159 #[inline]
160 fn not(self) -> Self::Output {
161 MetadataFilter::not(self)
162 }
163}