qubit_metadata/
metadata_filter.rs1use serde::{
32 Deserialize,
33 Serialize,
34};
35
36use crate::{
37 Condition,
38 Metadata,
39};
40
41#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
61pub enum MetadataFilter {
62 Condition(Condition),
64 And(Vec<MetadataFilter>),
66 Or(Vec<MetadataFilter>),
68 Not(Box<MetadataFilter>),
70}
71
72impl MetadataFilter {
73 pub fn equal<T: Serialize>(key: impl Into<String>, value: T) -> Self {
77 Self::Condition(Condition::Equal {
78 key: key.into(),
79 value: serde_json::to_value(value)
80 .expect("MetadataFilter::equal: value must be serializable"),
81 })
82 }
83
84 pub fn not_equal<T: Serialize>(key: impl Into<String>, value: T) -> Self {
86 Self::Condition(Condition::NotEqual {
87 key: key.into(),
88 value: serde_json::to_value(value)
89 .expect("MetadataFilter::not_equal: value must be serializable"),
90 })
91 }
92
93 pub fn greater<T: Serialize>(key: impl Into<String>, value: T) -> Self {
95 Self::Condition(Condition::Greater {
96 key: key.into(),
97 value: serde_json::to_value(value)
98 .expect("MetadataFilter::greater: value must be serializable"),
99 })
100 }
101
102 pub fn greater_equal<T: Serialize>(key: impl Into<String>, value: T) -> Self {
104 Self::Condition(Condition::GreaterEqual {
105 key: key.into(),
106 value: serde_json::to_value(value)
107 .expect("MetadataFilter::greater_equal: value must be serializable"),
108 })
109 }
110
111 pub fn less<T: Serialize>(key: impl Into<String>, value: T) -> Self {
113 Self::Condition(Condition::Less {
114 key: key.into(),
115 value: serde_json::to_value(value)
116 .expect("MetadataFilter::less: value must be serializable"),
117 })
118 }
119
120 pub fn less_equal<T: Serialize>(key: impl Into<String>, value: T) -> Self {
122 Self::Condition(Condition::LessEqual {
123 key: key.into(),
124 value: serde_json::to_value(value)
125 .expect("MetadataFilter::less_equal: value must be serializable"),
126 })
127 }
128
129 pub fn exists(key: impl Into<String>) -> Self {
131 Self::Condition(Condition::Exists { key: key.into() })
132 }
133
134 pub fn not_exists(key: impl Into<String>) -> Self {
136 Self::Condition(Condition::NotExists { key: key.into() })
137 }
138
139 pub fn in_values<T, I>(key: impl Into<String>, values: I) -> Self
141 where
142 T: Serialize,
143 I: IntoIterator<Item = T>,
144 {
145 let values = values
146 .into_iter()
147 .map(|v| {
148 serde_json::to_value(v)
149 .expect("MetadataFilter::in_values: each value must be serializable")
150 })
151 .collect();
152 Self::Condition(Condition::In {
153 key: key.into(),
154 values,
155 })
156 }
157
158 pub fn not_in_values<T, I>(key: impl Into<String>, values: I) -> Self
160 where
161 T: Serialize,
162 I: IntoIterator<Item = T>,
163 {
164 let values = values
165 .into_iter()
166 .map(|v| {
167 serde_json::to_value(v)
168 .expect("MetadataFilter::not_in_values: each value must be serializable")
169 })
170 .collect();
171 Self::Condition(Condition::NotIn {
172 key: key.into(),
173 values,
174 })
175 }
176
177 #[must_use]
184 pub fn and(self, other: MetadataFilter) -> Self {
185 match self {
186 MetadataFilter::And(mut children) => {
187 children.push(other);
188 MetadataFilter::And(children)
189 }
190 _ => MetadataFilter::And(vec![self, other]),
191 }
192 }
193
194 #[must_use]
199 pub fn or(self, other: MetadataFilter) -> Self {
200 match self {
201 MetadataFilter::Or(mut children) => {
202 children.push(other);
203 MetadataFilter::Or(children)
204 }
205 _ => MetadataFilter::Or(vec![self, other]),
206 }
207 }
208
209 #[allow(clippy::should_implement_trait)]
211 #[must_use]
212 pub fn not(self) -> Self {
213 !self
214 }
215
216 pub fn matches(&self, meta: &Metadata) -> bool {
220 match self {
221 MetadataFilter::Condition(cond) => cond.matches(meta),
222 MetadataFilter::And(children) => children.iter().all(|f| f.matches(meta)),
223 MetadataFilter::Or(children) => children.iter().any(|f| f.matches(meta)),
224 MetadataFilter::Not(inner) => !inner.matches(meta),
225 }
226 }
227}
228
229impl std::ops::Not for MetadataFilter {
230 type Output = MetadataFilter;
231
232 fn not(self) -> Self::Output {
233 MetadataFilter::Not(Box::new(self))
234 }
235}