1use crate::compiler::prelude::*;
2use crate::datadog_filter::{
3 Filter, Matcher, Resolver, Run, build_matcher,
4 regex::{wildcard_regex, word_regex},
5};
6use crate::datadog_search_syntax::{Comparison, ComparisonValue, Field, ParseError, QueryNode};
7use crate::owned_value_path;
8use crate::path::{OwnedValuePath, PathParseError, parse_value_path};
9use crate::prelude::function::Error::InvalidArgument;
10use std::borrow::Cow;
11
12const QUERY_KEYWORD: &str = "query";
13
14#[derive(Clone, Copy, Debug)]
15pub struct MatchDatadogQuery;
16
17impl Function for MatchDatadogQuery {
18 fn identifier(&self) -> &'static str {
19 "match_datadog_query"
20 }
21
22 fn usage(&self) -> &'static str {
23 "Matches an object against a [Datadog Search Syntax](https://docs.datadoghq.com/logs/explorer/search_syntax/) query."
24 }
25
26 fn category(&self) -> &'static str {
27 Category::Object.as_ref()
28 }
29
30 fn return_kind(&self) -> u16 {
31 kind::BOOLEAN
32 }
33
34 fn examples(&self) -> &'static [Example] {
35 &[
36 example! {
37 title: "OR query",
38 source: r#"match_datadog_query({"message": "contains this and that"}, "this OR that")"#,
39 result: Ok("true"),
40 },
41 example! {
42 title: "AND query",
43 source: r#"match_datadog_query({"message": "contains only this"}, "this AND that")"#,
44 result: Ok("false"),
45 },
46 example! {
47 title: "Attribute wildcard",
48 source: r#"match_datadog_query({"name": "foobar"}, "@name:foo*")"#,
49 result: Ok("true"),
50 },
51 example! {
52 title: "Tag range",
53 source: r#"match_datadog_query({"tags": ["a:x", "b:y", "c:z"]}, s'b:["x" TO "z"]')"#,
54 result: Ok("true"),
55 },
56 ]
57 }
58
59 fn compile(
60 &self,
61 state: &state::TypeState,
62 _ctx: &mut FunctionCompileContext,
63 arguments: ArgumentList,
64 ) -> Compiled {
65 let value = arguments.required("value");
66 let query_value = arguments.required_literal(QUERY_KEYWORD, state)?;
67
68 let query = query_value
70 .try_bytes_utf8_lossy()
71 .expect("datadog search query should be a UTF8 string");
72
73 let node: QueryNode = query.parse().map_err(|e: ParseError| {
75 Box::new(ExpressionError::from(e.to_string())) as Box<dyn DiagnosticMessage>
76 })?;
77
78 let filter = build_matcher(&node, &VrlFilter).map_err(|_| {
82 Box::new(InvalidArgument {
83 keyword: QUERY_KEYWORD,
84 value: query_value,
85 error: "failed to build matcher",
86 }) as Box<dyn DiagnosticMessage>
87 })?;
88
89 Ok(MatchDatadogQueryFn { value, filter }.as_expr())
90 }
91
92 fn parameters(&self) -> &'static [Parameter] {
93 const PARAMETERS: &[Parameter] = &[
94 Parameter::required("value", kind::OBJECT, "The object."),
95 Parameter::required("query", kind::BYTES, "The Datadog Search Syntax query."),
96 ];
97 PARAMETERS
98 }
99}
100
101#[derive(Debug, Clone)]
102struct MatchDatadogQueryFn {
103 value: Box<dyn Expression>,
104 filter: Box<dyn Matcher<Value>>,
105}
106
107impl FunctionExpression for MatchDatadogQueryFn {
108 fn resolve(&self, ctx: &mut Context) -> Resolved {
109 let value = self.value.resolve(ctx)?;
110
111 Ok(self.filter.run(&value).into())
114 }
115
116 fn type_def(&self, _: &state::TypeState) -> TypeDef {
117 type_def()
118 }
119}
120
121fn type_def() -> TypeDef {
122 TypeDef::boolean().infallible()
123}
124
125#[derive(Default, Clone)]
126struct VrlFilter;
127
128impl Resolver for VrlFilter {}
131
132impl Filter<Value> for VrlFilter {
134 fn exists(&self, field: Field) -> Result<Box<dyn Matcher<Value>>, PathParseError> {
135 let buf = lookup_field(&field)?;
136
137 Ok(match field {
138 Field::Tag(tag) => {
140 let starts_with = format!("{tag}:");
141
142 resolve_value(
143 buf,
144 Run::boxed(move |value| match value {
145 Value::Array(v) => v.iter().any(|v| {
146 let str_value = string_value(v);
147
148 str_value == tag || str_value.starts_with(&starts_with)
150 }),
151 _ => false,
152 }),
153 )
154 }
155 Field::Reserved(f) if f == "tags" => resolve_value(
157 buf,
158 Run::boxed(|value| match value {
159 Value::Array(v) => v.iter().any(|v| v == value),
160 _ => false,
161 }),
162 ),
163
164 _ => resolve_value(buf, Box::new(true)),
166 })
167 }
168
169 fn equals(
170 &self,
171 field: Field,
172 to_match: &str,
173 ) -> Result<Box<dyn Matcher<Value>>, PathParseError> {
174 let buf = lookup_field(&field)?;
175
176 Ok(match field {
177 Field::Default(_) => {
179 let re = word_regex(to_match);
180
181 resolve_value(
182 buf,
183 Run::boxed(move |value| match value {
184 Value::Bytes(val) => re.is_match(&String::from_utf8_lossy(val)),
185 _ => false,
186 }),
187 )
188 }
189 Field::Reserved(f) if f == "tags" => {
191 let to_match = to_match.to_owned();
192
193 resolve_value(
194 buf,
195 Run::boxed(move |value| match value {
196 Value::Array(v) => {
197 v.contains(&Value::Bytes(Bytes::copy_from_slice(to_match.as_bytes())))
198 }
199 _ => false,
200 }),
201 )
202 }
203 Field::Tag(tag) => {
205 let value_bytes = Value::Bytes(format!("{tag}:{to_match}").into());
206
207 resolve_value(
208 buf,
209 Run::boxed(move |value| match value {
210 Value::Array(v) => v.contains(&value_bytes),
211 _ => false,
212 }),
213 )
214 }
215 _ => {
217 let to_match = to_match.to_owned();
218
219 resolve_value(
220 buf,
221 Run::boxed(move |value| string_value(value) == to_match),
222 )
223 }
224 })
225 }
226
227 fn prefix(
228 &self,
229 field: Field,
230 prefix: &str,
231 ) -> Result<Box<dyn Matcher<Value>>, PathParseError> {
232 let buf = lookup_field(&field)?;
233
234 Ok(match field {
235 Field::Default(_) => {
237 let re = word_regex(&format!("{prefix}*"));
238
239 resolve_value(
240 buf,
241 Run::boxed(move |value| re.is_match(&string_value(value))),
242 )
243 }
244 Field::Tag(tag) => {
246 let starts_with = format!("{tag}:{prefix}");
247
248 resolve_value(
249 buf,
250 Run::boxed(move |value| match value {
251 Value::Array(v) => {
252 v.iter().any(|v| string_value(v).starts_with(&starts_with))
253 }
254 _ => false,
255 }),
256 )
257 }
258 _ => {
260 let prefix = prefix.to_owned();
261
262 resolve_value(
263 buf,
264 Run::boxed(move |value| string_value(value).starts_with(&prefix)),
265 )
266 }
267 })
268 }
269
270 fn wildcard(
271 &self,
272 field: Field,
273 wildcard: &str,
274 ) -> Result<Box<dyn Matcher<Value>>, PathParseError> {
275 let buf = lookup_field(&field)?;
276
277 Ok(match field {
278 Field::Default(_) => {
279 let re = word_regex(wildcard);
280
281 resolve_value(
282 buf,
283 Run::boxed(move |value| re.is_match(&string_value(value))),
284 )
285 }
286 Field::Tag(tag) => {
287 let re = wildcard_regex(&format!("{tag}:{wildcard}"));
288
289 resolve_value(
290 buf,
291 Run::boxed(move |value| match value {
292 Value::Array(v) => v.iter().any(|v| re.is_match(&string_value(v))),
293 _ => false,
294 }),
295 )
296 }
297 _ => {
298 let re = wildcard_regex(wildcard);
299
300 resolve_value(
301 buf,
302 Run::boxed(move |value| re.is_match(&string_value(value))),
303 )
304 }
305 })
306 }
307
308 #[allow(clippy::cast_precision_loss)] fn compare(
310 &self,
311 field: Field,
312 comparator: Comparison,
313 comparison_value: ComparisonValue,
314 ) -> Result<Box<dyn Matcher<Value>>, PathParseError> {
315 let buf = lookup_field(&field)?;
316
317 let rhs = Cow::from(comparison_value.to_string());
318
319 Ok(match field {
320 Field::Attribute(_) => {
322 resolve_value(
323 buf,
324 Run::boxed(move |value| match (value, &comparison_value) {
325 (Value::Integer(lhs), ComparisonValue::Integer(rhs)) => match comparator {
327 Comparison::Lt => *lhs < *rhs,
328 Comparison::Lte => *lhs <= *rhs,
329 Comparison::Gt => *lhs > *rhs,
330 Comparison::Gte => *lhs >= *rhs,
331 },
332 (Value::Integer(lhs), ComparisonValue::Float(rhs)) => match comparator {
334 Comparison::Lt => (*lhs as f64) < *rhs,
335 Comparison::Lte => *lhs as f64 <= *rhs,
336 Comparison::Gt => *lhs as f64 > *rhs,
337 Comparison::Gte => *lhs as f64 >= *rhs,
338 },
339 (Value::Float(lhs), ComparisonValue::Float(rhs)) => {
341 let lhs = lhs.into_inner();
342 match comparator {
343 Comparison::Lt => lhs < *rhs,
344 Comparison::Lte => lhs <= *rhs,
345 Comparison::Gt => lhs > *rhs,
346 Comparison::Gte => lhs >= *rhs,
347 }
348 }
349 (Value::Float(lhs), ComparisonValue::Integer(rhs)) => {
351 let lhs = lhs.into_inner();
352 match comparator {
353 Comparison::Lt => lhs < *rhs as f64,
354 Comparison::Lte => lhs <= *rhs as f64,
355 Comparison::Gt => lhs > *rhs as f64,
356 Comparison::Gte => lhs >= *rhs as f64,
357 }
358 }
359 (_, ComparisonValue::String(rhs)) => {
361 let lhs = string_value(value);
362 let rhs = Cow::from(rhs);
363
364 match comparator {
365 Comparison::Lt => lhs < rhs,
366 Comparison::Lte => lhs <= rhs,
367 Comparison::Gt => lhs > rhs,
368 Comparison::Gte => lhs >= rhs,
369 }
370 }
371 _ => {
373 let lhs = string_value(value);
374
375 match comparator {
376 Comparison::Lt => lhs < rhs,
377 Comparison::Lte => lhs <= rhs,
378 Comparison::Gt => lhs > rhs,
379 Comparison::Gte => lhs >= rhs,
380 }
381 }
382 }),
383 )
384 }
385 Field::Tag(_) => resolve_value(
387 buf,
388 Run::boxed(move |value| match value {
389 Value::Array(v) => v.iter().any(|v| match string_value(v).split_once(':') {
390 Some((_, lhs)) => {
391 let lhs = Cow::from(lhs);
392
393 match comparator {
394 Comparison::Lt => lhs < rhs,
395 Comparison::Lte => lhs <= rhs,
396 Comparison::Gt => lhs > rhs,
397 Comparison::Gte => lhs >= rhs,
398 }
399 }
400 _ => false,
401 }),
402 _ => false,
403 }),
404 ),
405 _ => resolve_value(
407 buf,
408 Run::boxed(move |value| {
409 let lhs = string_value(value);
410
411 match comparator {
412 Comparison::Lt => lhs < rhs,
413 Comparison::Lte => lhs <= rhs,
414 Comparison::Gt => lhs > rhs,
415 Comparison::Gte => lhs >= rhs,
416 }
417 }),
418 ),
419 })
420 }
421}
422
423fn resolve_value(
424 buf: OwnedValuePath,
425 match_fn: Box<dyn Matcher<Value>>,
426) -> Box<dyn Matcher<Value>> {
427 let func = move |obj: &Value| {
428 let Some(value) = obj.get(&buf) else {
430 return false;
431 };
432
433 match_fn.run(value)
434 };
435
436 Run::boxed(func)
437}
438
439fn lookup_field(field: &Field) -> Result<OwnedValuePath, PathParseError> {
442 match field {
443 Field::Default(p) | Field::Reserved(p) | Field::Attribute(p) => {
444 parse_value_path(p.as_str())
445 }
446 Field::Tag(_) => Ok(owned_value_path!("tags")),
447 }
448}
449
450fn string_value(value: &Value) -> Cow<'_, str> {
454 match value {
455 Value::Bytes(val) => String::from_utf8_lossy(val),
456 _ => Cow::from(value.to_string()),
457 }
458}
459
460#[cfg(test)]
461mod test {
462 use crate::value;
463
464 use super::*;
465
466 test_function![
467 match_datadog_query => MatchDatadogQuery;
468
469 message_exists {
470 args: func_args![value: value!({"message": "test message"}), query: "_exists_:message"],
471 want: Ok(true),
472 tdef: type_def(),
473 }
474
475 not_message_exists {
476 args: func_args![value: value!({"message": "test message"}), query: "NOT _exists_:message"],
477 want: Ok(false),
478 tdef: type_def(),
479 }
480
481 negate_message_exists {
482 args: func_args![value: value!({"message": "test message"}), query: "-_exists_:message"],
483 want: Ok(false),
484 tdef: type_def(),
485 }
486
487 facet_exists {
488 args: func_args![value: value!({"a": "value" }), query: "_exists_:@a"],
489 want: Ok(true),
490 tdef: type_def(),
491 }
492
493 not_facet_exists {
494 args: func_args![value: value!({"a": "value" }), query: "NOT _exists_:@a"],
495 want: Ok(false),
496 tdef: type_def(),
497 }
498
499 negate_facet_exists {
500 args: func_args![value: value!({"a": "value" }), query: "-_exists_:@a"],
501 want: Ok(false),
502 tdef: type_def(),
503 }
504
505 hyphen_facet_exists {
506 args: func_args![value: value!({"a-b": "value"}), query: "_exists_:@a-b"],
507 want: Ok(true),
508 tdef: type_def(),
509 }
510
511 tag_bare {
512 args: func_args![value: value!({"tags": ["a","b","c"]}), query: "tags:a"],
513 want: Ok(true),
514 tdef: type_def(),
515 }
516
517 tag_bare_no_match {
518 args: func_args![value: value!({"tags": ["a","b","c"]}), query: "tags:d"],
519 want: Ok(false),
520 tdef: type_def(),
521 }
522
523 not_tag_bare {
524 args: func_args![value: value!({"tags": ["a","b","c"]}), query: "NOT tags:a"],
525 want: Ok(false),
526 tdef: type_def(),
527 }
528
529 negate_tag_bare {
530 args: func_args![value: value!({"tags": ["a","b","c"]}), query: "-tags:a"],
531 want: Ok(false),
532 tdef: type_def(),
533 }
534
535 tag_exists_bare {
536 args: func_args![value: value!({"tags": ["a","b","c"]}), query: "_exists_:a"],
537 want: Ok(true),
538 tdef: type_def(),
539 }
540
541 not_tag_exists_bare {
542 args: func_args![value: value!({"tags": ["a","b","c"]}), query: "NOT _exists_:a"],
543 want: Ok(false),
544 tdef: type_def(),
545 }
546
547 negate_tag_exists_bare {
548 args: func_args![value: value!({"tags": ["a","b","c"]}), query: "-_exists_:a"],
549 want: Ok(false),
550 tdef: type_def(),
551 }
552
553 tag_exists {
554 args: func_args![value: value!({"tags": ["a:1","b:2","c:3"]}), query: "_exists_:a"],
555 want: Ok(true),
556 tdef: type_def(),
557 }
558
559 not_tag_exists {
560 args: func_args![value: value!({"tags": ["a:1","b:2","c:3"]}), query: "NOT _exists_:a"],
561 want: Ok(false),
562 tdef: type_def(),
563 }
564
565 negate_tag_exists {
566 args: func_args![value: value!({"tags": ["a:1","b:2","c:3"]}), query: "-_exists_:a"],
567 want: Ok(false),
568 tdef: type_def(),
569 }
570
571 message_missing {
572 args: func_args![value: value!({}), query: "_missing_:message"],
573 want: Ok(true),
574 tdef: type_def(),
575 }
576
577 not_message_missing {
578 args: func_args![value: value!({}), query: "NOT _missing_:message"],
579 want: Ok(false),
580 tdef: type_def(),
581 }
582
583 negate_message_missing {
584 args: func_args![value: value!({}), query: "-_missing_:message"],
585 want: Ok(false),
586 tdef: type_def(),
587 }
588
589 facet_missing {
590 args: func_args![value: value!({"b": "value" }), query: "_missing_:@a"],
591 want: Ok(true),
592 tdef: type_def(),
593 }
594
595 not_facet_missing {
596 args: func_args![value: value!({"b": "value" }), query: "NOT _missing_:@a"],
597 want: Ok(false),
598 tdef: type_def(),
599 }
600
601 negate_facet_missing {
602 args: func_args![value: value!({"b": "value" }), query: "-_missing_:@a"],
603 want: Ok(false),
604 tdef: type_def(),
605 }
606
607 hyphen_facet_missing {
608 args: func_args![value: value!({"a-b": "value"}), query: "_missing_:@c-d"],
609 want: Ok(true),
610 tdef: type_def(),
611 }
612
613 tag_bare_missing {
614 args: func_args![value: value!({"tags": ["b","c"]}), query: "_missing_:a"],
615 want: Ok(true),
616 tdef: type_def(),
617 }
618
619 not_tag_bare_missing {
620 args: func_args![value: value!({"tags": ["b","c"]}), query: "NOT _missing_:a"],
621 want: Ok(false),
622 tdef: type_def(),
623 }
624
625 negate_tag_bare_missing {
626 args: func_args![value: value!({"tags": ["b","c"]}), query: "-_missing_:a"],
627 want: Ok(false),
628 tdef: type_def(),
629 }
630
631 tag_missing {
632 args: func_args![value: value!({"tags": ["b:1","c:2"]}), query: "_missing_:a"],
633 want: Ok(true),
634 tdef: type_def(),
635 }
636
637 not_tag_missing {
638 args: func_args![value: value!({"tags": ["b:1","c:2"]}), query: "NOT _missing_:a"],
639 want: Ok(false),
640 tdef: type_def(),
641 }
642
643 negate_tag_missing {
644 args: func_args![value: value!({"tags": ["b:1","c:2"]}), query: "-_missing_:a"],
645 want: Ok(false),
646 tdef: type_def(),
647 }
648
649 equals_message {
650 args: func_args![value: value!({"message": "match by word boundary"}), query: "match"],
651 want: Ok(true),
652 tdef: type_def(),
653 }
654
655 not_equals_message {
656 args: func_args![value: value!({"message": "match by word boundary"}), query: "NOT match"],
657 want: Ok(false),
658 tdef: type_def(),
659 }
660
661 negate_equals_message {
662 args: func_args![value: value!({"message": "match by word boundary"}), query: "-match"],
663 want: Ok(false),
664 tdef: type_def(),
665 }
666
667 equals_message_no_match {
668 args: func_args![value: value!({"message": "another value"}), query: "match"],
669 want: Ok(false),
670 tdef: type_def(),
671 }
672
673 not_equals_message_no_match {
674 args: func_args![value: value!({"message": "another value"}), query: "NOT match"],
675 want: Ok(true),
676 tdef: type_def(),
677 }
678
679 negate_equals_message_no_match {
680 args: func_args![value: value!({"message": "another value"}), query: "-match"],
681 want: Ok(true),
682 tdef: type_def(),
683 }
684
685 equals_tag {
686 args: func_args![value: value!({"tags": ["x:1", "y:2", "z:3"]}), query: "y:2"],
687 want: Ok(true),
688 tdef: type_def(),
689 }
690
691 not_equals_tag {
692 args: func_args![value: value!({"tags": ["x:1", "y:2", "z:3"]}), query: "NOT y:2"],
693 want: Ok(false),
694 tdef: type_def(),
695 }
696
697 negate_equals_tag {
698 args: func_args![value: value!({"tags": ["x:1", "y:2", "z:3"]}), query: "-y:2"],
699 want: Ok(false),
700 tdef: type_def(),
701 }
702
703 equals_tag_no_match {
704 args: func_args![value: value!({"tags": ["x:1", "y:2", "z:3"]}), query: "y:3"],
705 want: Ok(false),
706 tdef: type_def(),
707 }
708
709 not_equals_tag_no_match {
710 args: func_args![value: value!({"tags": ["x:1", "y:2", "z:3"]}), query: "NOT y:3"],
711 want: Ok(true),
712 tdef: type_def(),
713 }
714
715 negate_equals_tag_no_match {
716 args: func_args![value: value!({"tags": ["x:1", "y:2", "z:3"]}), query: "-y:3"],
717 want: Ok(true),
718 tdef: type_def(),
719 }
720
721 equals_facet {
722 args: func_args![value: value!({"z": 1}), query: "@z:1"],
723 want: Ok(true),
724 tdef: type_def(),
725 }
726
727 not_equals_facet {
728 args: func_args![value: value!({"z": 1}), query: "NOT @z:1"],
729 want: Ok(false),
730 tdef: type_def(),
731 }
732
733 negate_equals_facet {
734 args: func_args![value: value!({"z": 1}), query: "-@z:1"],
735 want: Ok(false),
736 tdef: type_def(),
737 }
738
739 wildcard_prefix_message {
740 args: func_args![value: value!({"message": "vector"}), query: "*tor"],
741 want: Ok(true),
742 tdef: type_def(),
743 }
744
745 not_wildcard_prefix_message {
746 args: func_args![value: value!({"message": "vector"}), query: "NOT *tor"],
747 want: Ok(false),
748 tdef: type_def(),
749 }
750
751 negate_wildcard_prefix_message {
752 args: func_args![value: value!({"message": "vector"}), query: "-*tor"],
753 want: Ok(false),
754 tdef: type_def(),
755 }
756
757 wildcard_prefix_message_no_match {
758 args: func_args![value: value!({"message": "torvec"}), query: "*tor"],
759 want: Ok(false),
760 tdef: type_def(),
761 }
762
763 not_wildcard_prefix_message_no_match {
764 args: func_args![value: value!({"message": "torvec"}), query: "NOT *tor"],
765 want: Ok(true),
766 tdef: type_def(),
767 }
768
769 negate_wildcard_prefix_message_no_match {
770 args: func_args![value: value!({"message": "torvec"}), query: "-*tor"],
771 want: Ok(true),
772 tdef: type_def(),
773 }
774
775 wildcard_prefix_tag {
776 args: func_args![value: value!({"tags": ["a:vector"]}), query: "a:*tor"],
777 want: Ok(true),
778 tdef: type_def(),
779 }
780
781 not_wildcard_prefix_tag {
782 args: func_args![value: value!({"tags": ["a:vector"]}), query: "NOT a:*tor"],
783 want: Ok(false),
784 tdef: type_def(),
785 }
786
787 negate_wildcard_prefix_tag {
788 args: func_args![value: value!({"tags": ["a:vector"]}), query: "-a:*tor"],
789 want: Ok(false),
790 tdef: type_def(),
791 }
792
793 wildcard_prefix_tag_no_match {
794 args: func_args![value: value!({"tags": ["b:vector"]}), query: "a:*tor"],
795 want: Ok(false),
796 tdef: type_def(),
797 }
798
799 not_wildcard_prefix_tag_no_match {
800 args: func_args![value: value!({"tags": ["b:vector"]}), query: "NOT a:*tor"],
801 want: Ok(true),
802 tdef: type_def(),
803 }
804
805 negate_wildcard_prefix_tag_no_match {
806 args: func_args![value: value!({"tags": ["b:vector"]}), query: "-a:*tor"],
807 want: Ok(true),
808 tdef: type_def(),
809 }
810
811 wildcard_prefix_facet {
812 args: func_args![value: value!({"a": "vector"}), query: "@a:*tor"],
813 want: Ok(true),
814 tdef: type_def(),
815 }
816
817 not_wildcard_prefix_facet {
818 args: func_args![value: value!({"a": "vector"}), query: "NOT @a:*tor"],
819 want: Ok(false),
820 tdef: type_def(),
821 }
822
823 negate_wildcard_prefix_facet {
824 args: func_args![value: value!({"a": "vector"}), query: "-@a:*tor"],
825 want: Ok(false),
826 tdef: type_def(),
827 }
828
829 wildcard_prefix_facet_no_match {
830 args: func_args![value: value!({"b": "vector"}), query: "@a:*tor"],
831 want: Ok(false),
832 tdef: type_def(),
833 }
834
835 not_wildcard_prefix_facet_no_match {
836 args: func_args![value: value!({"b": "vector"}), query: "NOT @a:*tor"],
837 want: Ok(true),
838 tdef: type_def(),
839 }
840
841 negate_wildcard_prefix_facet_no_match {
842 args: func_args![value: value!({"b": "vector"}), query: "-@a:*tor"],
843 want: Ok(true),
844 tdef: type_def(),
845 }
846
847 wildcard_suffix_message {
848 args: func_args![value: value!({"message": "vector"}), query: "vec*"],
849 want: Ok(true),
850 tdef: type_def(),
851 }
852
853 not_wildcard_suffix_message {
854 args: func_args![value: value!({"message": "vector"}), query: "NOT vec*"],
855 want: Ok(false),
856 tdef: type_def(),
857 }
858
859 negate_wildcard_suffix_message {
860 args: func_args![value: value!({"message": "vector"}), query: "-vec*"],
861 want: Ok(false),
862 tdef: type_def(),
863 }
864
865 wildcard_suffix_message_no_match {
866 args: func_args![value: value!({"message": "torvec"}), query: "vec*"],
867 want: Ok(false),
868 tdef: type_def(),
869 }
870
871 not_wildcard_suffix_message_no_match {
872 args: func_args![value: value!({"message": "torvec"}), query: "NOT vec*"],
873 want: Ok(true),
874 tdef: type_def(),
875 }
876
877 negate_wildcard_suffix_message_no_match {
878 args: func_args![value: value!({"message": "torvec"}), query: "-vec*"],
879 want: Ok(true),
880 tdef: type_def(),
881 }
882
883 wildcard_suffix_tag {
884 args: func_args![value: value!({"tags": ["a:vector"]}), query: "a:vec*"],
885 want: Ok(true),
886 tdef: type_def(),
887 }
888
889 not_wildcard_suffix_tag {
890 args: func_args![value: value!({"tags": ["a:vector"]}), query: "NOT a:vec*"],
891 want: Ok(false),
892 tdef: type_def(),
893 }
894
895 negate_wildcard_suffix_tag {
896 args: func_args![value: value!({"tags": ["a:vector"]}), query: "-a:vec*"],
897 want: Ok(false),
898 tdef: type_def(),
899 }
900
901 wildcard_suffix_tag_no_match {
902 args: func_args![value: value!({"tags": ["b:vector"]}), query: "a:vec*"],
903 want: Ok(false),
904 tdef: type_def(),
905 }
906
907 not_wildcard_suffix_tag_no_match {
908 args: func_args![value: value!({"tags": ["b:vector"]}), query: "NOT a:vec*"],
909 want: Ok(true),
910 tdef: type_def(),
911 }
912
913 negate_wildcard_suffix_tag_no_match {
914 args: func_args![value: value!({"tags": ["b:vector"]}), query: "-a:vec*"],
915 want: Ok(true),
916 tdef: type_def(),
917 }
918
919 wildcard_suffix_facet {
920 args: func_args![value: value!({"a": "vector"}), query: "@a:vec*"],
921 want: Ok(true),
922 tdef: type_def(),
923 }
924
925 not_wildcard_suffix_facet {
926 args: func_args![value: value!({"a": "vector"}), query: "NOT @a:vec*"],
927 want: Ok(false),
928 tdef: type_def(),
929 }
930
931 negate_wildcard_suffix_facet {
932 args: func_args![value: value!({"a": "vector"}), query: "-@a:vec*"],
933 want: Ok(false),
934 tdef: type_def(),
935 }
936
937 wildcard_suffix_facet_no_match {
938 args: func_args![value: value!({"b": "vector"}), query: "@a:vec*"],
939 want: Ok(false),
940 tdef: type_def(),
941 }
942
943 not_wildcard_suffix_facet_no_match {
944 args: func_args![value: value!({"b": "vector"}), query: "NOT @a:vec*"],
945 want: Ok(true),
946 tdef: type_def(),
947 }
948
949 negate_wildcard_suffix_facet_no_match {
950 args: func_args![value: value!({"b": "vector"}), query: "-@a:vec*"],
951 want: Ok(true),
952 tdef: type_def(),
953 }
954
955 wildcard_multiple_message {
956 args: func_args![value: value!({"message": "vector"}), query: "v*c*r"],
957 want: Ok(true),
958 tdef: type_def(),
959 }
960
961 not_wildcard_multiple_message {
962 args: func_args![value: value!({"message": "vector"}), query: "NOT v*c*r"],
963 want: Ok(false),
964 tdef: type_def(),
965 }
966
967 negate_wildcard_multiple_message {
968 args: func_args![value: value!({"message": "vector"}), query: "-v*c*r"],
969 want: Ok(false),
970 tdef: type_def(),
971 }
972
973 wildcard_multiple_message_no_match {
974 args: func_args![value: value!({"message": "torvec"}), query: "v*c*r"],
975 want: Ok(false),
976 tdef: type_def(),
977 }
978
979 not_wildcard_multiple_message_no_match {
980 args: func_args![value: value!({"message": "torvec"}), query: "NOT v*c*r"],
981 want: Ok(true),
982 tdef: type_def(),
983 }
984
985 negate_wildcard_multiple_message_no_match {
986 args: func_args![value: value!({"message": "torvec"}), query: "-v*c*r"],
987 want: Ok(true),
988 tdef: type_def(),
989 }
990
991 wildcard_multiple_tag {
992 args: func_args![value: value!({"tags": ["a:vector"]}), query: "a:v*c*r"],
993 want: Ok(true),
994 tdef: type_def(),
995 }
996
997 not_wildcard_multiple_tag {
998 args: func_args![value: value!({"tags": ["a:vector"]}), query: "NOT a:v*c*r"],
999 want: Ok(false),
1000 tdef: type_def(),
1001 }
1002
1003 negate_wildcard_multiple_tag {
1004 args: func_args![value: value!({"tags": ["a:vector"]}), query: "-a:v*c*r"],
1005 want: Ok(false),
1006 tdef: type_def(),
1007 }
1008
1009 wildcard_multiple_tag_no_match {
1010 args: func_args![value: value!({"tags": ["b:vector"]}), query: "a:v*c*r"],
1011 want: Ok(false),
1012 tdef: type_def(),
1013 }
1014
1015 not_wildcard_multiple_tag_no_match {
1016 args: func_args![value: value!({"tags": ["b:vector"]}), query: "NOT a:v*c*r"],
1017 want: Ok(true),
1018 tdef: type_def(),
1019 }
1020
1021 negate_wildcard_multiple_tag_no_match {
1022 args: func_args![value: value!({"tags": ["b:vector"]}), query: "-a:v*c*r"],
1023 want: Ok(true),
1024 tdef: type_def(),
1025 }
1026
1027 wildcard_multiple_facet {
1028 args: func_args![value: value!({"a": "vector"}), query: "@a:v*c*r"],
1029 want: Ok(true),
1030 tdef: type_def(),
1031 }
1032
1033 not_wildcard_multiple_facet {
1034 args: func_args![value: value!({"a": "vector"}), query: "NOT @a:v*c*r"],
1035 want: Ok(false),
1036 tdef: type_def(),
1037 }
1038
1039 negate_wildcard_multiple_facet {
1040 args: func_args![value: value!({"a": "vector"}), query: "-@a:v*c*r"],
1041 want: Ok(false),
1042 tdef: type_def(),
1043 }
1044
1045 wildcard_multiple_facet_no_match {
1046 args: func_args![value: value!({"b": "vector"}), query: "@a:v*c*r"],
1047 want: Ok(false),
1048 tdef: type_def(),
1049 }
1050
1051 not_wildcard_multiple_facet_no_match {
1052 args: func_args![value: value!({"b": "vector"}), query: "NOT @a:v*c*r"],
1053 want: Ok(true),
1054 tdef: type_def(),
1055 }
1056
1057 negate_wildcard_multiple_facet_no_match {
1058 args: func_args![value: value!({"b": "vector"}), query: "-@a:v*c*r"],
1059 want: Ok(true),
1060 tdef: type_def(),
1061 }
1062
1063 range_message_unbounded {
1064 args: func_args![value: value!({"message": "1"}), query: "[* TO *]"],
1065 want: Ok(true),
1066 tdef: type_def(),
1067 }
1068
1069 not_range_message_unbounded {
1070 args: func_args![value: value!({"message": "1"}), query: "NOT [* TO *]"],
1071 want: Ok(false),
1072 tdef: type_def(),
1073 }
1074
1075 negate_range_message_unbounded {
1076 args: func_args![value: value!({"message": "1"}), query: "-[* TO *]"],
1077 want: Ok(false),
1078 tdef: type_def(),
1079 }
1080
1081 range_message_lower_bound {
1082 args: func_args![value: value!({"message": "400"}), query: "[4 TO *]"],
1083 want: Ok(true),
1084 tdef: type_def(),
1085 }
1086
1087 not_range_message_lower_bound {
1088 args: func_args![value: value!({"message": "400"}), query: "NOT [4 TO *]"],
1089 want: Ok(false),
1090 tdef: type_def(),
1091 }
1092
1093 negate_range_message_lower_bound {
1094 args: func_args![value: value!({"message": "400"}), query: "-[4 TO *]"],
1095 want: Ok(false),
1096 tdef: type_def(),
1097 }
1098
1099 range_message_lower_bound_no_match {
1100 args: func_args![value: value!({"message": "400"}), query: "[50 TO *]"],
1101 want: Ok(false),
1102 tdef: type_def(),
1103 }
1104
1105 not_range_message_lower_bound_no_match {
1106 args: func_args![value: value!({"message": "400"}), query: "NOT [50 TO *]"],
1107 want: Ok(true),
1108 tdef: type_def(),
1109 }
1110
1111 negate_range_message_lower_bound_no_match {
1112 args: func_args![value: value!({"message": "400"}), query: "-[50 TO *]"],
1113 want: Ok(true),
1114 tdef: type_def(),
1115 }
1116
1117 range_message_lower_bound_string {
1118 args: func_args![value: value!({"message": "400"}), query: r#"["4" TO *]"#],
1119 want: Ok(true),
1120 tdef: type_def(),
1121 }
1122
1123 not_range_message_lower_bound_string {
1124 args: func_args![value: value!({"message": "400"}), query: r#"NOT ["4" TO *]"#],
1125 want: Ok(false),
1126 tdef: type_def(),
1127 }
1128
1129 negate_range_message_lower_bound_string {
1130 args: func_args![value: value!({"message": "400"}), query: r#"-["4" TO *]"#],
1131 want: Ok(false),
1132 tdef: type_def(),
1133 }
1134
1135 range_message_lower_bound_string_no_match {
1136 args: func_args![value: value!({"message": "400"}), query: r#"["50" TO *]"#],
1137 want: Ok(false),
1138 tdef: type_def(),
1139 }
1140
1141 not_range_message_lower_bound_string_no_match {
1142 args: func_args![value: value!({"message": "400"}), query: r#"NOT ["50" TO *]"#],
1143 want: Ok(true),
1144 tdef: type_def(),
1145 }
1146
1147 negate_range_message_lower_bound_string_no_match {
1148 args: func_args![value: value!({"message": "400"}), query: r#"-["50" TO *]"#],
1149 want: Ok(true),
1150 tdef: type_def(),
1151 }
1152
1153 range_message_upper_bound {
1154 args: func_args![value: value!({"message": "300"}), query: "[* TO 4]"],
1155 want: Ok(true),
1156 tdef: type_def(),
1157 }
1158
1159 not_range_message_upper_bound {
1160 args: func_args![value: value!({"message": "300"}), query: "NOT [* TO 4]"],
1161 want: Ok(false),
1162 tdef: type_def(),
1163 }
1164
1165 negate_range_message_upper_bound {
1166 args: func_args![value: value!({"message": "300"}), query: "-[* TO 4]"],
1167 want: Ok(false),
1168 tdef: type_def(),
1169 }
1170
1171 range_message_upper_bound_no_match {
1172 args: func_args![value: value!({"message": "50"}), query: "[* TO 400]"],
1173 want: Ok(false),
1174 tdef: type_def(),
1175 }
1176
1177 not_range_message_upper_bound_no_match {
1178 args: func_args![value: value!({"message": "50"}), query: "NOT [* TO 400]"],
1179 want: Ok(true),
1180 tdef: type_def(),
1181 }
1182
1183 negate_range_message_upper_bound_no_match {
1184 args: func_args![value: value!({"message": "50"}), query: "-[* TO 400]"],
1185 want: Ok(true),
1186 tdef: type_def(),
1187 }
1188
1189 range_message_upper_bound_string {
1190 args: func_args![value: value!({"message": "300"}), query: r#"[* TO "4"]"#],
1191 want: Ok(true),
1192 tdef: type_def(),
1193 }
1194
1195 not_range_message_upper_bound_string {
1196 args: func_args![value: value!({"message": "300"}), query: r#"NOT [* TO "4"]"#],
1197 want: Ok(false),
1198 tdef: type_def(),
1199 }
1200
1201 negate_range_message_upper_bound_string {
1202 args: func_args![value: value!({"message": "300"}), query: r#"-[* TO "4"]"#],
1203 want: Ok(false),
1204 tdef: type_def(),
1205 }
1206
1207 range_message_upper_bound_string_no_match {
1208 args: func_args![value: value!({"message": "50"}), query: r#"[* TO "400"]"#],
1209 want: Ok(false),
1210 tdef: type_def(),
1211 }
1212
1213 not_range_message_upper_bound_string_no_match {
1214 args: func_args![value: value!({"message": "50"}), query: r#"NOT [* TO "400"]"#],
1215 want: Ok(true),
1216 tdef: type_def(),
1217 }
1218
1219 negate_range_message_upper_bound_string_no_match {
1220 args: func_args![value: value!({"message": "50"}), query: r#"NOT [* TO "400"]"#],
1221 want: Ok(true),
1222 tdef: type_def(),
1223 }
1224
1225 range_message_between {
1226 args: func_args![value: value!({"message": 500}), query: "[1 TO 6]"],
1227 want: Ok(true),
1228 tdef: type_def(),
1229 }
1230
1231 not_range_message_between {
1232 args: func_args![value: value!({"message": 500}), query: "NOT [1 TO 6]"],
1233 want: Ok(false),
1234 tdef: type_def(),
1235 }
1236
1237 negate_range_message_between {
1238 args: func_args![value: value!({"message": 500}), query: "-[1 TO 6]"],
1239 want: Ok(false),
1240 tdef: type_def(),
1241 }
1242
1243 range_message_between_no_match {
1244 args: func_args![value: value!({"message": 70}), query: "[1 TO 6]"],
1245 want: Ok(false),
1246 tdef: type_def(),
1247 }
1248
1249 not_range_message_between_no_match {
1250 args: func_args![value: value!({"message": 70}), query: "NOT [1 TO 6]"],
1251 want: Ok(true),
1252 tdef: type_def(),
1253 }
1254
1255 negate_range_message_between_no_match {
1256 args: func_args![value: value!({"message": 70}), query: "-[1 TO 6]"],
1257 want: Ok(true),
1258 tdef: type_def(),
1259 }
1260
1261 range_message_between_string {
1262 args: func_args![value: value!({"message": "500"}), query: r#"["1" TO "6"]"#],
1263 want: Ok(true),
1264 tdef: type_def(),
1265 }
1266
1267 not_range_message_between_string {
1268 args: func_args![value: value!({"message": "500"}), query: r#"NOT ["1" TO "6"]"#],
1269 want: Ok(false),
1270 tdef: type_def(),
1271 }
1272
1273 negate_range_message_between_string {
1274 args: func_args![value: value!({"message": "500"}), query: r#"-["1" TO "6"]"#],
1275 want: Ok(false),
1276 tdef: type_def(),
1277 }
1278
1279 range_message_between_no_match_string {
1280 args: func_args![value: value!({"message": "70"}), query: r#"["1" TO "6"]"#],
1281 want: Ok(false),
1282 tdef: type_def(),
1283 }
1284
1285 not_range_message_between_no_match_string {
1286 args: func_args![value: value!({"message": "70"}), query: r#"NOT ["1" TO "6"]"#],
1287 want: Ok(true),
1288 tdef: type_def(),
1289 }
1290
1291 negate_range_message_between_no_match_string {
1292 args: func_args![value: value!({"message": "70"}), query: r#"-["1" TO "6"]"#],
1293 want: Ok(true),
1294 tdef: type_def(),
1295 }
1296
1297 range_tag_key {
1298 args: func_args![value: value!({"tags": ["a"]}), query: "a:[* TO *]"],
1299 want: Ok(true),
1300 tdef: type_def(),
1301 }
1302
1303 range_tag_key_no_match {
1304 args: func_args![value: value!({"tags": ["b"]}), query: "a:[* TO *]"],
1305 want: Ok(false),
1306 tdef: type_def(),
1307 }
1308
1309 range_tag_unbounded {
1310 args: func_args![value: value!({"tags": ["a:1"]}), query: "a:[* TO *]"],
1311 want: Ok(true),
1312 tdef: type_def(),
1313 }
1314
1315 not_range_tag_unbounded {
1316 args: func_args![value: value!({"tags": ["a:1"]}), query: "NOT a:[* TO *]"],
1317 want: Ok(false),
1318 tdef: type_def(),
1319 }
1320
1321 negate_range_tag_unbounded {
1322 args: func_args![value: value!({"tags": ["a:1"]}), query: "-a:[* TO *]"],
1323 want: Ok(false),
1324 tdef: type_def(),
1325 }
1326
1327 range_tag_lower_bound {
1328 args: func_args![value: value!({"tags": ["a:400"]}), query: "a:[4 TO *]"],
1329 want: Ok(true),
1330 tdef: type_def(),
1331 }
1332
1333 not_range_tag_lower_bound {
1334 args: func_args![value: value!({"tags": ["a:400"]}), query: "NOT a:[4 TO *]"],
1335 want: Ok(false),
1336 tdef: type_def(),
1337 }
1338
1339 negate_range_tag_lower_bound {
1340 args: func_args![value: value!({"tags": ["a:400"]}), query: "-a:[4 TO *]"],
1341 want: Ok(false),
1342 tdef: type_def(),
1343 }
1344
1345 range_tag_lower_bound_no_match {
1346 args: func_args![value: value!({"tags": ["a:400"]}), query: "a:[50 TO *]"],
1347 want: Ok(false),
1348 tdef: type_def(),
1349 }
1350
1351 not_range_tag_lower_bound_no_match {
1352 args: func_args![value: value!({"tags": ["a:400"]}), query: "NOT a:[50 TO *]"],
1353 want: Ok(true),
1354 tdef: type_def(),
1355 }
1356
1357 negate_range_tag_lower_bound_no_match {
1358 args: func_args![value: value!({"tags": ["a:400"]}), query: "-a:[50 TO *]"],
1359 want: Ok(true),
1360 tdef: type_def(),
1361 }
1362
1363 range_tag_lower_bound_string {
1364 args: func_args![value: value!({"tags": ["a:400"]}), query: r#"a:["4" TO *]"#],
1365 want: Ok(true),
1366 tdef: type_def(),
1367 }
1368
1369 not_range_tag_lower_bound_string {
1370 args: func_args![value: value!({"tags": ["a:400"]}), query: r#"NOT a:["4" TO *]"#],
1371 want: Ok(false),
1372 tdef: type_def(),
1373 }
1374
1375 negate_range_tag_lower_bound_string {
1376 args: func_args![value: value!({"tags": ["a:400"]}), query: r#"-a:["4" TO *]"#],
1377 want: Ok(false),
1378 tdef: type_def(),
1379 }
1380
1381 range_tag_lower_bound_string_no_match {
1382 args: func_args![value: value!({"tags": ["a:400"]}), query: r#"a:["50" TO *]"#],
1383 want: Ok(false),
1384 tdef: type_def(),
1385 }
1386
1387 not_range_tag_lower_bound_string_no_match {
1388 args: func_args![value: value!({"tags": ["a:400"]}), query: r#"NOT a:["50" TO *]"#],
1389 want: Ok(true),
1390 tdef: type_def(),
1391 }
1392
1393 negate_range_tag_lower_bound_string_no_match {
1394 args: func_args![value: value!({"tags": ["a:400"]}), query: r#"-a:["50" TO *]"#],
1395 want: Ok(true),
1396 tdef: type_def(),
1397 }
1398
1399 range_tag_upper_bound {
1400 args: func_args![value: value!({"tags": ["a:300"]}), query: "a:[* TO 4]"],
1401 want: Ok(true),
1402 tdef: type_def(),
1403 }
1404
1405 not_range_tag_upper_bound {
1406 args: func_args![value: value!({"tags": ["a:300"]}), query: "NOT a:[* TO 4]"],
1407 want: Ok(false),
1408 tdef: type_def(),
1409 }
1410
1411 negate_range_tag_upper_bound {
1412 args: func_args![value: value!({"tags": ["a:300"]}), query: "-a:[* TO 4]"],
1413 want: Ok(false),
1414 tdef: type_def(),
1415 }
1416
1417 range_tag_upper_bound_no_match {
1418 args: func_args![value: value!({"tags": ["a:50"]}), query: "a:[* TO 400]"],
1419 want: Ok(false),
1420 tdef: type_def(),
1421 }
1422
1423 not_range_tag_upper_bound_no_match {
1424 args: func_args![value: value!({"tags": ["a:50"]}), query: "NOT a:[* TO 400]"],
1425 want: Ok(true),
1426 tdef: type_def(),
1427 }
1428
1429 negate_range_tag_upper_bound_no_match {
1430 args: func_args![value: value!({"tags": ["a:50"]}), query: "-a:[* TO 400]"],
1431 want: Ok(true),
1432 tdef: type_def(),
1433 }
1434
1435 range_tag_upper_bound_string {
1436 args: func_args![value: value!({"tags": ["a:300"]}), query: r#"a:[* TO "4"]"#],
1437 want: Ok(true),
1438 tdef: type_def(),
1439 }
1440
1441 not_range_tag_upper_bound_string {
1442 args: func_args![value: value!({"tags": ["a:300"]}), query: r#"NOT a:[* TO "4"]"#],
1443 want: Ok(false),
1444 tdef: type_def(),
1445 }
1446
1447 negate_range_tag_upper_bound_string {
1448 args: func_args![value: value!({"tags": ["a:300"]}), query: r#"-a:[* TO "4"]"#],
1449 want: Ok(false),
1450 tdef: type_def(),
1451 }
1452
1453 range_tag_upper_bound_string_no_match {
1454 args: func_args![value: value!({"tags": ["a:50"]}), query: r#"a:[* TO "400"]"#],
1455 want: Ok(false),
1456 tdef: type_def(),
1457 }
1458
1459 not_range_tag_upper_bound_string_no_match {
1460 args: func_args![value: value!({"tags": ["a:50"]}), query: r#"NOT a:[* TO "400"]"#],
1461 want: Ok(true),
1462 tdef: type_def(),
1463 }
1464
1465 negate_range_tag_upper_bound_string_no_match {
1466 args: func_args![value: value!({"tags": ["a:50"]}), query: r#"-a:[* TO "400"]"#],
1467 want: Ok(true),
1468 tdef: type_def(),
1469 }
1470
1471 range_tag_between {
1472 args: func_args![value: value!({"tags": ["a:500"]}), query: "a:[1 TO 6]"],
1473 want: Ok(true),
1474 tdef: type_def(),
1475 }
1476
1477 not_range_tag_between {
1478 args: func_args![value: value!({"tags": ["a:500"]}), query: "NOT a:[1 TO 6]"],
1479 want: Ok(false),
1480 tdef: type_def(),
1481 }
1482
1483 negate_range_tag_between {
1484 args: func_args![value: value!({"tags": ["a:500"]}), query: "-a:[1 TO 6]"],
1485 want: Ok(false),
1486 tdef: type_def(),
1487 }
1488
1489 range_tag_between_no_match {
1490 args: func_args![value: value!({"tags": ["a:70"]}), query: "a:[1 TO 6]"],
1491 want: Ok(false),
1492 tdef: type_def(),
1493 }
1494
1495 not_range_tag_between_no_match {
1496 args: func_args![value: value!({"tags": ["a:70"]}), query: "NOT a:[1 TO 6]"],
1497 want: Ok(true),
1498 tdef: type_def(),
1499 }
1500
1501 negate_range_tag_between_no_match {
1502 args: func_args![value: value!({"tags": ["a:70"]}), query: "-a:[1 TO 6]"],
1503 want: Ok(true),
1504 tdef: type_def(),
1505 }
1506
1507 range_tag_between_string {
1508 args: func_args![value: value!({"tags": ["a:500"]}), query: r#"a:["1" TO "6"]"#],
1509 want: Ok(true),
1510 tdef: type_def(),
1511 }
1512
1513 not_range_tag_between_string {
1514 args: func_args![value: value!({"tags": ["a:500"]}), query: r#"NOT a:["1" TO "6"]"#],
1515 want: Ok(false),
1516 tdef: type_def(),
1517 }
1518
1519 negate_range_tag_between_string {
1520 args: func_args![value: value!({"tags": ["a:500"]}), query: r#"-a:["1" TO "6"]"#],
1521 want: Ok(false),
1522 tdef: type_def(),
1523 }
1524
1525 range_tag_between_no_match_string {
1526 args: func_args![value: value!({"tags": ["a:70"]}), query: r#"a:["1" TO "6"]"#],
1527 want: Ok(false),
1528 tdef: type_def(),
1529 }
1530
1531 not_range_tag_between_no_match_string {
1532 args: func_args![value: value!({"tags": ["a:70"]}), query: r#"NOT a:["1" TO "6"]"#],
1533 want: Ok(true),
1534 tdef: type_def(),
1535 }
1536
1537 negate_range_tag_between_no_match_string {
1538 args: func_args![value: value!({"tags": ["a:70"]}), query: r#"-a:["1" TO "6"]"#],
1539 want: Ok(true),
1540 tdef: type_def(),
1541 }
1542
1543 range_facet_unbounded {
1544 args: func_args![value: value!({"a": 1}), query: "@a:[* TO *]"],
1545 want: Ok(true),
1546 tdef: type_def(),
1547 }
1548
1549 not_range_facet_unbounded {
1550 args: func_args![value: value!({"a": 1}), query: "NOT @a:[* TO *]"],
1551 want: Ok(false),
1552 tdef: type_def(),
1553 }
1554
1555 negate_range_facet_unbounded {
1556 args: func_args![value: value!({"a": 1}), query: "-@a:[* TO *]"],
1557 want: Ok(false),
1558 tdef: type_def(),
1559 }
1560
1561 range_facet_lower_bound {
1562 args: func_args![value: value!({"a": 5}), query: "@a:[4 TO *]"],
1563 want: Ok(true),
1564 tdef: type_def(),
1565 }
1566
1567 not_range_facet_lower_bound {
1568 args: func_args![value: value!({"a": 5}), query: "NOT @a:[4 TO *]"],
1569 want: Ok(false),
1570 tdef: type_def(),
1571 }
1572
1573 negate_range_facet_lower_bound {
1574 args: func_args![value: value!({"a": 5}), query: "-@a:[4 TO *]"],
1575 want: Ok(false),
1576 tdef: type_def(),
1577 }
1578
1579 range_facet_lower_bound_no_match {
1580 args: func_args![value: value!({"a": 5}), query: "@a:[50 TO *]"],
1581 want: Ok(false),
1582 tdef: type_def(),
1583 }
1584
1585 not_range_facet_lower_bound_no_match {
1586 args: func_args![value: value!({"a": 5}), query: "NOT @a:[50 TO *]"],
1587 want: Ok(true),
1588 tdef: type_def(),
1589 }
1590
1591 negate_range_facet_lower_bound_no_match {
1592 args: func_args![value: value!({"a": 5}), query: "-@a:[50 TO *]"],
1593 want: Ok(true),
1594 tdef: type_def(),
1595 }
1596
1597 range_facet_lower_bound_string {
1598 args: func_args![value: value!({"a": "5"}), query: r#"@a:["4" TO *]"#],
1599 want: Ok(true),
1600 tdef: type_def(),
1601 }
1602
1603 not_range_facet_lower_bound_string {
1604 args: func_args![value: value!({"a": "5"}), query: r#"NOT @a:["4" TO *]"#],
1605 want: Ok(false),
1606 tdef: type_def(),
1607 }
1608
1609 negate_range_facet_lower_bound_string {
1610 args: func_args![value: value!({"a": "5"}), query: r#"-@a:["4" TO *]"#],
1611 want: Ok(false),
1612 tdef: type_def(),
1613 }
1614
1615 range_facet_lower_bound_string_no_match {
1616 args: func_args![value: value!({"a": "400"}), query: r#"@a:["50" TO *]"#],
1617 want: Ok(false),
1618 tdef: type_def(),
1619 }
1620
1621 not_range_facet_lower_bound_string_no_match {
1622 args: func_args![value: value!({"a": "400"}), query: r#"NOT @a:["50" TO *]"#],
1623 want: Ok(true),
1624 tdef: type_def(),
1625 }
1626
1627 negate_range_facet_lower_bound_string_no_match {
1628 args: func_args![value: value!({"a": "400"}), query: r#"-@a:["50" TO *]"#],
1629 want: Ok(true),
1630 tdef: type_def(),
1631 }
1632
1633 range_facet_upper_bound {
1634 args: func_args![value: value!({"a": 1}), query: "@a:[* TO 4]"],
1635 want: Ok(true),
1636 tdef: type_def(),
1637 }
1638
1639 not_range_facet_upper_bound {
1640 args: func_args![value: value!({"a": 1}), query: "NOT @a:[* TO 4]"],
1641 want: Ok(false),
1642 tdef: type_def(),
1643 }
1644
1645 negate_range_facet_upper_bound {
1646 args: func_args![value: value!({"a": 1}), query: "-@a:[* TO 4]"],
1647 want: Ok(false),
1648 tdef: type_def(),
1649 }
1650
1651 range_facet_upper_bound_no_match {
1652 args: func_args![value: value!({"a": 500}), query: "@a:[* TO 400]"],
1653 want: Ok(false),
1654 tdef: type_def(),
1655 }
1656
1657 not_range_facet_upper_bound_no_match {
1658 args: func_args![value: value!({"a": 500}), query: "NOT @a:[* TO 400]"],
1659 want: Ok(true),
1660 tdef: type_def(),
1661 }
1662
1663 negate_range_facet_upper_bound_no_match {
1664 args: func_args![value: value!({"a": 500}), query: "-@a:[* TO 400]"],
1665 want: Ok(true),
1666 tdef: type_def(),
1667 }
1668
1669 range_facet_upper_bound_string {
1670 args: func_args![value: value!({"a": "3"}), query: r#"@a:[* TO "4"]"#],
1671 want: Ok(true),
1672 tdef: type_def(),
1673 }
1674
1675 not_range_facet_upper_bound_string {
1676 args: func_args![value: value!({"a": "3"}), query: r#"NOT @a:[* TO "4"]"#],
1677 want: Ok(false),
1678 tdef: type_def(),
1679 }
1680
1681 negate_range_facet_upper_bound_string {
1682 args: func_args![value: value!({"a": "3"}), query: r#"-@a:[* TO "4"]"#],
1683 want: Ok(false),
1684 tdef: type_def(),
1685 }
1686
1687 range_facet_upper_bound_string_no_match {
1688 args: func_args![value: value!({"a": "5"}), query: r#"@a:[* TO "400"]"#],
1689 want: Ok(false),
1690 tdef: type_def(),
1691 }
1692
1693 not_range_facet_upper_bound_string_no_match {
1694 args: func_args![value: value!({"a": "5"}), query: r#"NOT @a:[* TO "400"]"#],
1695 want: Ok(true),
1696 tdef: type_def(),
1697 }
1698
1699 negate_range_facet_upper_bound_string_no_match {
1700 args: func_args![value: value!({"a": "5"}), query: r#"-@a:[* TO "400"]"#],
1701 want: Ok(true),
1702 tdef: type_def(),
1703 }
1704
1705 range_facet_between {
1706 args: func_args![value: value!({"a": 5}), query: "@a:[1 TO 6]"],
1707 want: Ok(true),
1708 tdef: type_def(),
1709 }
1710
1711 not_range_facet_between {
1712 args: func_args![value: value!({"a": 5}), query: "NOT @a:[1 TO 6]"],
1713 want: Ok(false),
1714 tdef: type_def(),
1715 }
1716
1717 negate_range_facet_between {
1718 args: func_args![value: value!({"a": 5}), query: "-@a:[1 TO 6]"],
1719 want: Ok(false),
1720 tdef: type_def(),
1721 }
1722
1723 range_facet_between_no_match {
1724 args: func_args![value: value!({"a": 200}), query: "@a:[1 TO 6]"],
1725 want: Ok(false),
1726 tdef: type_def(),
1727 }
1728
1729 not_range_facet_between_no_match {
1730 args: func_args![value: value!({"a": 200}), query: "NOT @a:[1 TO 6]"],
1731 want: Ok(true),
1732 tdef: type_def(),
1733 }
1734
1735 negate_range_facet_between_no_match {
1736 args: func_args![value: value!({"a": 200}), query: "-@a:[1 TO 6]"],
1737 want: Ok(true),
1738 tdef: type_def(),
1739 }
1740
1741 range_facet_between_string {
1742 args: func_args![value: value!({"a": "500"}), query: r#"@a:["1" TO "6"]"#],
1743 want: Ok(true),
1744 tdef: type_def(),
1745 }
1746
1747 not_range_facet_between_string {
1748 args: func_args![value: value!({"a": "500"}), query: r#"NOT @a:["1" TO "6"]"#],
1749 want: Ok(false),
1750 tdef: type_def(),
1751 }
1752
1753 negate_range_facet_between_string {
1754 args: func_args![value: value!({"a": "500"}), query: r#"-@a:["1" TO "6"]"#],
1755 want: Ok(false),
1756 tdef: type_def(),
1757 }
1758
1759 range_facet_between_no_match_string {
1760 args: func_args![value: value!({"a": "7"}), query: r#"@a:["1" TO "60"]"#],
1761 want: Ok(false),
1762 tdef: type_def(),
1763 }
1764
1765 not_range_facet_between_no_match_string {
1766 args: func_args![value: value!({"a": "7"}), query: r#"NOT @a:["1" TO "60"]"#],
1767 want: Ok(true),
1768 tdef: type_def(),
1769 }
1770
1771 negate_range_facet_between_no_match_string {
1772 args: func_args![value: value!({"a": "7"}), query: r#"-@a:["1" TO "60"]"#],
1773 want: Ok(true),
1774 tdef: type_def(),
1775 }
1776
1777 exclusive_range_message {
1778 args: func_args![value: value!({"message": "100"}), query: "{1 TO 2}"],
1779 want: Ok(true),
1780 tdef: type_def(),
1781 }
1782
1783 not_exclusive_range_message {
1784 args: func_args![value: value!({"message": "100"}), query: "NOT {1 TO 2}"],
1785 want: Ok(false),
1786 tdef: type_def(),
1787 }
1788
1789 negate_exclusive_range_message {
1790 args: func_args![value: value!({"message": "100"}), query: "-{1 TO 2}"],
1791 want: Ok(false),
1792 tdef: type_def(),
1793 }
1794
1795 exclusive_range_message_no_match {
1796 args: func_args![value: value!({"message": "1"}), query: "{1 TO 2}"],
1797 want: Ok(false),
1798 tdef: type_def(),
1799 }
1800
1801 not_exclusive_range_message_no_match {
1802 args: func_args![value: value!({"message": "1"}), query: "NOT {1 TO 2}"],
1803 want: Ok(true),
1804 tdef: type_def(),
1805 }
1806
1807 negate_exclusive_range_message_no_match {
1808 args: func_args![value: value!({"message": "1"}), query: "-{1 TO 2}"],
1809 want: Ok(true),
1810 tdef: type_def(),
1811 }
1812
1813 exclusive_range_message_lower {
1814 args: func_args![value: value!({"message": "200"}), query: "{1 TO *}"],
1815 want: Ok(true),
1816 tdef: type_def(),
1817 }
1818
1819 not_exclusive_range_message_lower {
1820 args: func_args![value: value!({"message": "200"}), query: "NOT {1 TO *}"],
1821 want: Ok(false),
1822 tdef: type_def(),
1823 }
1824
1825 negate_exclusive_range_message_lower {
1826 args: func_args![value: value!({"message": "200"}), query: "-{1 TO *}"],
1827 want: Ok(false),
1828 tdef: type_def(),
1829 }
1830
1831 exclusive_range_message_lower_no_match {
1832 args: func_args![value: value!({"message": "1"}), query: "{1 TO *}"],
1833 want: Ok(false),
1834 tdef: type_def(),
1835 }
1836
1837 not_exclusive_range_message_lower_no_match {
1838 args: func_args![value: value!({"message": "1"}), query: "NOT {1 TO *}"],
1839 want: Ok(true),
1840 tdef: type_def(),
1841 }
1842
1843 negate_exclusive_range_message_lower_no_match {
1844 args: func_args![value: value!({"message": "1"}), query: "-{1 TO *}"],
1845 want: Ok(true),
1846 tdef: type_def(),
1847 }
1848
1849 exclusive_range_message_upper {
1850 args: func_args![value: value!({"message": "200"}), query: "{* TO 3}"],
1851 want: Ok(true),
1852 tdef: type_def(),
1853 }
1854
1855 not_exclusive_range_message_upper {
1856 args: func_args![value: value!({"message": "200"}), query: "NOT {* TO 3}"],
1857 want: Ok(false),
1858 tdef: type_def(),
1859 }
1860
1861 negate_exclusive_range_message_upper {
1862 args: func_args![value: value!({"message": "200"}), query: "-{* TO 3}"],
1863 want: Ok(false),
1864 tdef: type_def(),
1865 }
1866
1867 exclusive_range_message_upper_no_match {
1868 args: func_args![value: value!({"message": "3"}), query: "{* TO 3}"],
1869 want: Ok(false),
1870 tdef: type_def(),
1871 }
1872
1873 not_exclusive_range_message_upper_no_match {
1874 args: func_args![value: value!({"message": "3"}), query: "NOT {* TO 3}"],
1875 want: Ok(true),
1876 tdef: type_def(),
1877 }
1878
1879 negate_exclusive_range_message_upper_no_match {
1880 args: func_args![value: value!({"message": "3"}), query: "-{* TO 3}"],
1881 want: Ok(true),
1882 tdef: type_def(),
1883 }
1884
1885 message_and {
1886 args: func_args![value: value!({"message": "this contains that"}), query: "this AND that"],
1887 want: Ok(true),
1888 tdef: type_def(),
1889 }
1890
1891 message_and_not {
1892 args: func_args![value: value!({"message": "this contains that"}), query: "this AND NOT that"],
1893 want: Ok(false),
1894 tdef: type_def(),
1895 }
1896
1897 message_or {
1898 args: func_args![value: value!({"message": "only contains that"}), query: "this OR that"],
1899 want: Ok(true),
1900 tdef: type_def(),
1901 }
1902
1903 message_or_not {
1904 args: func_args![value: value!({"message": "only contains that"}), query: "this OR NOT that"],
1905 want: Ok(false),
1906 tdef: type_def(),
1907 }
1908
1909 message_and_or {
1910 args: func_args![value: value!({"message": "this contains that"}), query: "this AND (that OR the_other)"],
1911 want: Ok(true),
1912 tdef: type_def(),
1913 }
1914
1915 not_message_and_or {
1916 args: func_args![value: value!({"message": "this contains that"}), query: "this AND NOT (that OR the_other)"],
1917 want: Ok(false),
1918 tdef: type_def(),
1919 }
1920
1921 negate_message_and_or {
1922 args: func_args![value: value!({"message": "this contains that"}), query: "this AND -(that OR the_other)"],
1923 want: Ok(false),
1924 tdef: type_def(),
1925 }
1926
1927 message_and_or_2 {
1928 args: func_args![value: value!({"message": "this contains the_other"}), query: "this AND (that OR the_other)"],
1929 want: Ok(true),
1930 tdef: type_def(),
1931 }
1932
1933 not_message_and_or_2 {
1934 args: func_args![value: value!({"message": "this contains the_other"}), query: "this AND NOT (that OR the_other)"],
1935 want: Ok(false),
1936 tdef: type_def(),
1937 }
1938
1939 negate_message_and_or_2 {
1940 args: func_args![value: value!({"message": "this contains the_other"}), query: "this AND -(that OR the_other)"],
1941 want: Ok(false),
1942 tdef: type_def(),
1943 }
1944
1945 message_or_and {
1946 args: func_args![value: value!({"message": "just this"}), query: "this OR (that AND the_other)"],
1947 want: Ok(true),
1948 tdef: type_def(),
1949 }
1950
1951 message_or_and_no_match {
1952 args: func_args![value: value!({"message": "that and nothing else"}), query: "this OR (that AND the_other)"],
1953 want: Ok(false),
1954 tdef: type_def(),
1955 }
1956
1957 message_or_and_2 {
1958 args: func_args![value: value!({"message": "that plus the_other"}), query: "this OR (that AND the_other)"],
1959 want: Ok(true),
1960 tdef: type_def(),
1961 }
1962
1963 message_or_and_2_no_match {
1964 args: func_args![value: value!({"message": "nothing plus the_other"}), query: "this OR (that AND the_other)"],
1965 want: Ok(false),
1966 tdef: type_def(),
1967 }
1968
1969 kitchen_sink {
1970 args: func_args![value: value!({"host": "this"}), query: "host:this OR ((@b:test* AND c:that) AND d:the_other @e:[1 TO 5])"],
1971 want: Ok(true),
1972 tdef: type_def(),
1973 }
1974
1975 kitchen_sink_2 {
1976 args: func_args![value: value!({"tags": ["c:that", "d:the_other"], "b": "testing", "e": 3}), query: "host:this OR ((@b:test* AND c:that) AND d:the_other @e:[1 TO 5])"],
1977 want: Ok(true),
1978 tdef: type_def(),
1979 }
1980
1981 integer_range_float_value_match {
1982 args: func_args![value: value!({"level": 7.0}), query: "@level:[7 TO 10]"],
1983 want: Ok(true),
1984 tdef: type_def(),
1985 }
1986
1987 integer_range_float_value_no_match {
1988 args: func_args![value: value!({"level": 6.9}), query: "@level:[7 TO 10]"],
1989 want: Ok(false),
1990 tdef: type_def(),
1991 }
1992
1993 float_range_integer_value_match {
1994 args: func_args![value: value!({"level": 7}), query: "@level:[7.0 TO 10.0]"],
1995 want: Ok(true),
1996 tdef: type_def(),
1997 }
1998
1999 float_range_integer_value_no_match {
2000 args: func_args![value: value!({"level": 6}), query: "@level:[7.0 TO 10.0]"],
2001 want: Ok(false),
2002 tdef: type_def(),
2003 }
2004
2005 path_parser_hyphen {
2006 args: func_args![value: value!({"a-b": "3"}), query: "@a-b:3"],
2007 want: Ok(true),
2008 tdef: type_def(),
2009 }
2010
2011 path_parser_failure {
2012 args: func_args![value: value!({"a-b": "3"}), query: "@a%:3"],
2013 want: Err("invalid argument"),
2014 tdef: type_def(),
2015 }
2016
2017 quoted_query_key_match {
2018 args: func_args![value: value!({"a-b": 1}), query: "@\\\"a-b\\\":1"],
2019 want: Ok(true),
2020 tdef: type_def(),
2021 }
2022 ];
2023}