use crate::compiler::prelude::*;
use crate::datadog_filter::{
Filter, Matcher, Resolver, Run, build_matcher,
regex::{wildcard_regex, word_regex},
};
use crate::datadog_search_syntax::{Comparison, ComparisonValue, Field, ParseError, QueryNode};
use crate::owned_value_path;
use crate::path::{OwnedValuePath, PathParseError, parse_value_path};
use crate::prelude::function::Error::InvalidArgument;
use std::borrow::Cow;
const QUERY_KEYWORD: &str = "query";
#[derive(Clone, Copy, Debug)]
pub struct MatchDatadogQuery;
impl Function for MatchDatadogQuery {
fn identifier(&self) -> &'static str {
"match_datadog_query"
}
fn usage(&self) -> &'static str {
"Matches an object against a [Datadog Search Syntax](https://docs.datadoghq.com/logs/explorer/search_syntax/) query."
}
fn category(&self) -> &'static str {
Category::Object.as_ref()
}
fn return_kind(&self) -> u16 {
kind::BOOLEAN
}
fn examples(&self) -> &'static [Example] {
&[
example! {
title: "OR query",
source: r#"match_datadog_query({"message": "contains this and that"}, "this OR that")"#,
result: Ok("true"),
},
example! {
title: "AND query",
source: r#"match_datadog_query({"message": "contains only this"}, "this AND that")"#,
result: Ok("false"),
},
example! {
title: "Attribute wildcard",
source: r#"match_datadog_query({"name": "foobar"}, "@name:foo*")"#,
result: Ok("true"),
},
example! {
title: "Tag range",
source: r#"match_datadog_query({"tags": ["a:x", "b:y", "c:z"]}, s'b:["x" TO "z"]')"#,
result: Ok("true"),
},
]
}
fn compile(
&self,
state: &state::TypeState,
_ctx: &mut FunctionCompileContext,
arguments: ArgumentList,
) -> Compiled {
let value = arguments.required("value");
let query_value = arguments.required_literal(QUERY_KEYWORD, state)?;
let query = query_value
.try_bytes_utf8_lossy()
.expect("datadog search query should be a UTF8 string");
let node: QueryNode = query.parse().map_err(|e: ParseError| {
Box::new(ExpressionError::from(e.to_string())) as Box<dyn DiagnosticMessage>
})?;
let filter = build_matcher(&node, &VrlFilter).map_err(|_| {
Box::new(InvalidArgument {
keyword: QUERY_KEYWORD,
value: query_value,
error: "failed to build matcher",
}) as Box<dyn DiagnosticMessage>
})?;
Ok(MatchDatadogQueryFn { value, filter }.as_expr())
}
fn parameters(&self) -> &'static [Parameter] {
const PARAMETERS: &[Parameter] = &[
Parameter::required("value", kind::OBJECT, "The object."),
Parameter::required("query", kind::BYTES, "The Datadog Search Syntax query."),
];
PARAMETERS
}
}
#[derive(Debug, Clone)]
struct MatchDatadogQueryFn {
value: Box<dyn Expression>,
filter: Box<dyn Matcher<Value>>,
}
impl FunctionExpression for MatchDatadogQueryFn {
fn resolve(&self, ctx: &mut Context) -> Resolved {
let value = self.value.resolve(ctx)?;
Ok(self.filter.run(&value).into())
}
fn type_def(&self, _: &state::TypeState) -> TypeDef {
type_def()
}
}
fn type_def() -> TypeDef {
TypeDef::boolean().infallible()
}
#[derive(Default, Clone)]
struct VrlFilter;
impl Resolver for VrlFilter {}
impl Filter<Value> for VrlFilter {
fn exists(&self, field: Field) -> Result<Box<dyn Matcher<Value>>, PathParseError> {
let buf = lookup_field(&field)?;
Ok(match field {
Field::Tag(tag) => {
let starts_with = format!("{tag}:");
resolve_value(
buf,
Run::boxed(move |value| match value {
Value::Array(v) => v.iter().any(|v| {
let str_value = string_value(v);
str_value == tag || str_value.starts_with(&starts_with)
}),
_ => false,
}),
)
}
Field::Reserved(f) if f == "tags" => resolve_value(
buf,
Run::boxed(|value| match value {
Value::Array(v) => v.iter().any(|v| v == value),
_ => false,
}),
),
_ => resolve_value(buf, Box::new(true)),
})
}
fn equals(
&self,
field: Field,
to_match: &str,
) -> Result<Box<dyn Matcher<Value>>, PathParseError> {
let buf = lookup_field(&field)?;
Ok(match field {
Field::Default(_) => {
let re = word_regex(to_match);
resolve_value(
buf,
Run::boxed(move |value| match value {
Value::Bytes(val) => re.is_match(&String::from_utf8_lossy(val)),
_ => false,
}),
)
}
Field::Reserved(f) if f == "tags" => {
let to_match = to_match.to_owned();
resolve_value(
buf,
Run::boxed(move |value| match value {
Value::Array(v) => {
v.contains(&Value::Bytes(Bytes::copy_from_slice(to_match.as_bytes())))
}
_ => false,
}),
)
}
Field::Tag(tag) => {
let value_bytes = Value::Bytes(format!("{tag}:{to_match}").into());
resolve_value(
buf,
Run::boxed(move |value| match value {
Value::Array(v) => v.contains(&value_bytes),
_ => false,
}),
)
}
_ => {
let to_match = to_match.to_owned();
resolve_value(
buf,
Run::boxed(move |value| string_value(value) == to_match),
)
}
})
}
fn prefix(
&self,
field: Field,
prefix: &str,
) -> Result<Box<dyn Matcher<Value>>, PathParseError> {
let buf = lookup_field(&field)?;
Ok(match field {
Field::Default(_) => {
let re = word_regex(&format!("{prefix}*"));
resolve_value(
buf,
Run::boxed(move |value| re.is_match(&string_value(value))),
)
}
Field::Tag(tag) => {
let starts_with = format!("{tag}:{prefix}");
resolve_value(
buf,
Run::boxed(move |value| match value {
Value::Array(v) => {
v.iter().any(|v| string_value(v).starts_with(&starts_with))
}
_ => false,
}),
)
}
_ => {
let prefix = prefix.to_owned();
resolve_value(
buf,
Run::boxed(move |value| string_value(value).starts_with(&prefix)),
)
}
})
}
fn wildcard(
&self,
field: Field,
wildcard: &str,
) -> Result<Box<dyn Matcher<Value>>, PathParseError> {
let buf = lookup_field(&field)?;
Ok(match field {
Field::Default(_) => {
let re = word_regex(wildcard);
resolve_value(
buf,
Run::boxed(move |value| re.is_match(&string_value(value))),
)
}
Field::Tag(tag) => {
let re = wildcard_regex(&format!("{tag}:{wildcard}"));
resolve_value(
buf,
Run::boxed(move |value| match value {
Value::Array(v) => v.iter().any(|v| re.is_match(&string_value(v))),
_ => false,
}),
)
}
_ => {
let re = wildcard_regex(wildcard);
resolve_value(
buf,
Run::boxed(move |value| re.is_match(&string_value(value))),
)
}
})
}
#[allow(clippy::cast_precision_loss)] fn compare(
&self,
field: Field,
comparator: Comparison,
comparison_value: ComparisonValue,
) -> Result<Box<dyn Matcher<Value>>, PathParseError> {
let buf = lookup_field(&field)?;
let rhs = Cow::from(comparison_value.to_string());
Ok(match field {
Field::Attribute(_) => {
resolve_value(
buf,
Run::boxed(move |value| match (value, &comparison_value) {
(Value::Integer(lhs), ComparisonValue::Integer(rhs)) => match comparator {
Comparison::Lt => *lhs < *rhs,
Comparison::Lte => *lhs <= *rhs,
Comparison::Gt => *lhs > *rhs,
Comparison::Gte => *lhs >= *rhs,
},
(Value::Integer(lhs), ComparisonValue::Float(rhs)) => match comparator {
Comparison::Lt => (*lhs as f64) < *rhs,
Comparison::Lte => *lhs as f64 <= *rhs,
Comparison::Gt => *lhs as f64 > *rhs,
Comparison::Gte => *lhs as f64 >= *rhs,
},
(Value::Float(lhs), ComparisonValue::Float(rhs)) => {
let lhs = lhs.into_inner();
match comparator {
Comparison::Lt => lhs < *rhs,
Comparison::Lte => lhs <= *rhs,
Comparison::Gt => lhs > *rhs,
Comparison::Gte => lhs >= *rhs,
}
}
(Value::Float(lhs), ComparisonValue::Integer(rhs)) => {
let lhs = lhs.into_inner();
match comparator {
Comparison::Lt => lhs < *rhs as f64,
Comparison::Lte => lhs <= *rhs as f64,
Comparison::Gt => lhs > *rhs as f64,
Comparison::Gte => lhs >= *rhs as f64,
}
}
(_, ComparisonValue::String(rhs)) => {
let lhs = string_value(value);
let rhs = Cow::from(rhs);
match comparator {
Comparison::Lt => lhs < rhs,
Comparison::Lte => lhs <= rhs,
Comparison::Gt => lhs > rhs,
Comparison::Gte => lhs >= rhs,
}
}
_ => {
let lhs = string_value(value);
match comparator {
Comparison::Lt => lhs < rhs,
Comparison::Lte => lhs <= rhs,
Comparison::Gt => lhs > rhs,
Comparison::Gte => lhs >= rhs,
}
}
}),
)
}
Field::Tag(_) => resolve_value(
buf,
Run::boxed(move |value| match value {
Value::Array(v) => v.iter().any(|v| match string_value(v).split_once(':') {
Some((_, lhs)) => {
let lhs = Cow::from(lhs);
match comparator {
Comparison::Lt => lhs < rhs,
Comparison::Lte => lhs <= rhs,
Comparison::Gt => lhs > rhs,
Comparison::Gte => lhs >= rhs,
}
}
_ => false,
}),
_ => false,
}),
),
_ => resolve_value(
buf,
Run::boxed(move |value| {
let lhs = string_value(value);
match comparator {
Comparison::Lt => lhs < rhs,
Comparison::Lte => lhs <= rhs,
Comparison::Gt => lhs > rhs,
Comparison::Gte => lhs >= rhs,
}
}),
),
})
}
}
fn resolve_value(
buf: OwnedValuePath,
match_fn: Box<dyn Matcher<Value>>,
) -> Box<dyn Matcher<Value>> {
let func = move |obj: &Value| {
let Some(value) = obj.get(&buf) else {
return false;
};
match_fn.run(value)
};
Run::boxed(func)
}
fn lookup_field(field: &Field) -> Result<OwnedValuePath, PathParseError> {
match field {
Field::Default(p) | Field::Reserved(p) | Field::Attribute(p) => {
parse_value_path(p.as_str())
}
Field::Tag(_) => Ok(owned_value_path!("tags")),
}
}
fn string_value(value: &Value) -> Cow<'_, str> {
match value {
Value::Bytes(val) => String::from_utf8_lossy(val),
_ => Cow::from(value.to_string()),
}
}
#[cfg(test)]
mod test {
use crate::value;
use super::*;
test_function![
match_datadog_query => MatchDatadogQuery;
message_exists {
args: func_args![value: value!({"message": "test message"}), query: "_exists_:message"],
want: Ok(true),
tdef: type_def(),
}
not_message_exists {
args: func_args![value: value!({"message": "test message"}), query: "NOT _exists_:message"],
want: Ok(false),
tdef: type_def(),
}
negate_message_exists {
args: func_args![value: value!({"message": "test message"}), query: "-_exists_:message"],
want: Ok(false),
tdef: type_def(),
}
facet_exists {
args: func_args![value: value!({"a": "value" }), query: "_exists_:@a"],
want: Ok(true),
tdef: type_def(),
}
not_facet_exists {
args: func_args![value: value!({"a": "value" }), query: "NOT _exists_:@a"],
want: Ok(false),
tdef: type_def(),
}
negate_facet_exists {
args: func_args![value: value!({"a": "value" }), query: "-_exists_:@a"],
want: Ok(false),
tdef: type_def(),
}
hyphen_facet_exists {
args: func_args![value: value!({"a-b": "value"}), query: "_exists_:@a-b"],
want: Ok(true),
tdef: type_def(),
}
tag_bare {
args: func_args![value: value!({"tags": ["a","b","c"]}), query: "tags:a"],
want: Ok(true),
tdef: type_def(),
}
tag_bare_no_match {
args: func_args![value: value!({"tags": ["a","b","c"]}), query: "tags:d"],
want: Ok(false),
tdef: type_def(),
}
not_tag_bare {
args: func_args![value: value!({"tags": ["a","b","c"]}), query: "NOT tags:a"],
want: Ok(false),
tdef: type_def(),
}
negate_tag_bare {
args: func_args![value: value!({"tags": ["a","b","c"]}), query: "-tags:a"],
want: Ok(false),
tdef: type_def(),
}
tag_exists_bare {
args: func_args![value: value!({"tags": ["a","b","c"]}), query: "_exists_:a"],
want: Ok(true),
tdef: type_def(),
}
not_tag_exists_bare {
args: func_args![value: value!({"tags": ["a","b","c"]}), query: "NOT _exists_:a"],
want: Ok(false),
tdef: type_def(),
}
negate_tag_exists_bare {
args: func_args![value: value!({"tags": ["a","b","c"]}), query: "-_exists_:a"],
want: Ok(false),
tdef: type_def(),
}
tag_exists {
args: func_args![value: value!({"tags": ["a:1","b:2","c:3"]}), query: "_exists_:a"],
want: Ok(true),
tdef: type_def(),
}
not_tag_exists {
args: func_args![value: value!({"tags": ["a:1","b:2","c:3"]}), query: "NOT _exists_:a"],
want: Ok(false),
tdef: type_def(),
}
negate_tag_exists {
args: func_args![value: value!({"tags": ["a:1","b:2","c:3"]}), query: "-_exists_:a"],
want: Ok(false),
tdef: type_def(),
}
message_missing {
args: func_args![value: value!({}), query: "_missing_:message"],
want: Ok(true),
tdef: type_def(),
}
not_message_missing {
args: func_args![value: value!({}), query: "NOT _missing_:message"],
want: Ok(false),
tdef: type_def(),
}
negate_message_missing {
args: func_args![value: value!({}), query: "-_missing_:message"],
want: Ok(false),
tdef: type_def(),
}
facet_missing {
args: func_args![value: value!({"b": "value" }), query: "_missing_:@a"],
want: Ok(true),
tdef: type_def(),
}
not_facet_missing {
args: func_args![value: value!({"b": "value" }), query: "NOT _missing_:@a"],
want: Ok(false),
tdef: type_def(),
}
negate_facet_missing {
args: func_args![value: value!({"b": "value" }), query: "-_missing_:@a"],
want: Ok(false),
tdef: type_def(),
}
hyphen_facet_missing {
args: func_args![value: value!({"a-b": "value"}), query: "_missing_:@c-d"],
want: Ok(true),
tdef: type_def(),
}
tag_bare_missing {
args: func_args![value: value!({"tags": ["b","c"]}), query: "_missing_:a"],
want: Ok(true),
tdef: type_def(),
}
not_tag_bare_missing {
args: func_args![value: value!({"tags": ["b","c"]}), query: "NOT _missing_:a"],
want: Ok(false),
tdef: type_def(),
}
negate_tag_bare_missing {
args: func_args![value: value!({"tags": ["b","c"]}), query: "-_missing_:a"],
want: Ok(false),
tdef: type_def(),
}
tag_missing {
args: func_args![value: value!({"tags": ["b:1","c:2"]}), query: "_missing_:a"],
want: Ok(true),
tdef: type_def(),
}
not_tag_missing {
args: func_args![value: value!({"tags": ["b:1","c:2"]}), query: "NOT _missing_:a"],
want: Ok(false),
tdef: type_def(),
}
negate_tag_missing {
args: func_args![value: value!({"tags": ["b:1","c:2"]}), query: "-_missing_:a"],
want: Ok(false),
tdef: type_def(),
}
equals_message {
args: func_args![value: value!({"message": "match by word boundary"}), query: "match"],
want: Ok(true),
tdef: type_def(),
}
not_equals_message {
args: func_args![value: value!({"message": "match by word boundary"}), query: "NOT match"],
want: Ok(false),
tdef: type_def(),
}
negate_equals_message {
args: func_args![value: value!({"message": "match by word boundary"}), query: "-match"],
want: Ok(false),
tdef: type_def(),
}
equals_message_no_match {
args: func_args![value: value!({"message": "another value"}), query: "match"],
want: Ok(false),
tdef: type_def(),
}
not_equals_message_no_match {
args: func_args![value: value!({"message": "another value"}), query: "NOT match"],
want: Ok(true),
tdef: type_def(),
}
negate_equals_message_no_match {
args: func_args![value: value!({"message": "another value"}), query: "-match"],
want: Ok(true),
tdef: type_def(),
}
equals_tag {
args: func_args![value: value!({"tags": ["x:1", "y:2", "z:3"]}), query: "y:2"],
want: Ok(true),
tdef: type_def(),
}
not_equals_tag {
args: func_args![value: value!({"tags": ["x:1", "y:2", "z:3"]}), query: "NOT y:2"],
want: Ok(false),
tdef: type_def(),
}
negate_equals_tag {
args: func_args![value: value!({"tags": ["x:1", "y:2", "z:3"]}), query: "-y:2"],
want: Ok(false),
tdef: type_def(),
}
equals_tag_no_match {
args: func_args![value: value!({"tags": ["x:1", "y:2", "z:3"]}), query: "y:3"],
want: Ok(false),
tdef: type_def(),
}
not_equals_tag_no_match {
args: func_args![value: value!({"tags": ["x:1", "y:2", "z:3"]}), query: "NOT y:3"],
want: Ok(true),
tdef: type_def(),
}
negate_equals_tag_no_match {
args: func_args![value: value!({"tags": ["x:1", "y:2", "z:3"]}), query: "-y:3"],
want: Ok(true),
tdef: type_def(),
}
equals_facet {
args: func_args![value: value!({"z": 1}), query: "@z:1"],
want: Ok(true),
tdef: type_def(),
}
not_equals_facet {
args: func_args![value: value!({"z": 1}), query: "NOT @z:1"],
want: Ok(false),
tdef: type_def(),
}
negate_equals_facet {
args: func_args![value: value!({"z": 1}), query: "-@z:1"],
want: Ok(false),
tdef: type_def(),
}
wildcard_prefix_message {
args: func_args![value: value!({"message": "vector"}), query: "*tor"],
want: Ok(true),
tdef: type_def(),
}
not_wildcard_prefix_message {
args: func_args![value: value!({"message": "vector"}), query: "NOT *tor"],
want: Ok(false),
tdef: type_def(),
}
negate_wildcard_prefix_message {
args: func_args![value: value!({"message": "vector"}), query: "-*tor"],
want: Ok(false),
tdef: type_def(),
}
wildcard_prefix_message_no_match {
args: func_args![value: value!({"message": "torvec"}), query: "*tor"],
want: Ok(false),
tdef: type_def(),
}
not_wildcard_prefix_message_no_match {
args: func_args![value: value!({"message": "torvec"}), query: "NOT *tor"],
want: Ok(true),
tdef: type_def(),
}
negate_wildcard_prefix_message_no_match {
args: func_args![value: value!({"message": "torvec"}), query: "-*tor"],
want: Ok(true),
tdef: type_def(),
}
wildcard_prefix_tag {
args: func_args![value: value!({"tags": ["a:vector"]}), query: "a:*tor"],
want: Ok(true),
tdef: type_def(),
}
not_wildcard_prefix_tag {
args: func_args![value: value!({"tags": ["a:vector"]}), query: "NOT a:*tor"],
want: Ok(false),
tdef: type_def(),
}
negate_wildcard_prefix_tag {
args: func_args![value: value!({"tags": ["a:vector"]}), query: "-a:*tor"],
want: Ok(false),
tdef: type_def(),
}
wildcard_prefix_tag_no_match {
args: func_args![value: value!({"tags": ["b:vector"]}), query: "a:*tor"],
want: Ok(false),
tdef: type_def(),
}
not_wildcard_prefix_tag_no_match {
args: func_args![value: value!({"tags": ["b:vector"]}), query: "NOT a:*tor"],
want: Ok(true),
tdef: type_def(),
}
negate_wildcard_prefix_tag_no_match {
args: func_args![value: value!({"tags": ["b:vector"]}), query: "-a:*tor"],
want: Ok(true),
tdef: type_def(),
}
wildcard_prefix_facet {
args: func_args![value: value!({"a": "vector"}), query: "@a:*tor"],
want: Ok(true),
tdef: type_def(),
}
not_wildcard_prefix_facet {
args: func_args![value: value!({"a": "vector"}), query: "NOT @a:*tor"],
want: Ok(false),
tdef: type_def(),
}
negate_wildcard_prefix_facet {
args: func_args![value: value!({"a": "vector"}), query: "-@a:*tor"],
want: Ok(false),
tdef: type_def(),
}
wildcard_prefix_facet_no_match {
args: func_args![value: value!({"b": "vector"}), query: "@a:*tor"],
want: Ok(false),
tdef: type_def(),
}
not_wildcard_prefix_facet_no_match {
args: func_args![value: value!({"b": "vector"}), query: "NOT @a:*tor"],
want: Ok(true),
tdef: type_def(),
}
negate_wildcard_prefix_facet_no_match {
args: func_args![value: value!({"b": "vector"}), query: "-@a:*tor"],
want: Ok(true),
tdef: type_def(),
}
wildcard_suffix_message {
args: func_args![value: value!({"message": "vector"}), query: "vec*"],
want: Ok(true),
tdef: type_def(),
}
not_wildcard_suffix_message {
args: func_args![value: value!({"message": "vector"}), query: "NOT vec*"],
want: Ok(false),
tdef: type_def(),
}
negate_wildcard_suffix_message {
args: func_args![value: value!({"message": "vector"}), query: "-vec*"],
want: Ok(false),
tdef: type_def(),
}
wildcard_suffix_message_no_match {
args: func_args![value: value!({"message": "torvec"}), query: "vec*"],
want: Ok(false),
tdef: type_def(),
}
not_wildcard_suffix_message_no_match {
args: func_args![value: value!({"message": "torvec"}), query: "NOT vec*"],
want: Ok(true),
tdef: type_def(),
}
negate_wildcard_suffix_message_no_match {
args: func_args![value: value!({"message": "torvec"}), query: "-vec*"],
want: Ok(true),
tdef: type_def(),
}
wildcard_suffix_tag {
args: func_args![value: value!({"tags": ["a:vector"]}), query: "a:vec*"],
want: Ok(true),
tdef: type_def(),
}
not_wildcard_suffix_tag {
args: func_args![value: value!({"tags": ["a:vector"]}), query: "NOT a:vec*"],
want: Ok(false),
tdef: type_def(),
}
negate_wildcard_suffix_tag {
args: func_args![value: value!({"tags": ["a:vector"]}), query: "-a:vec*"],
want: Ok(false),
tdef: type_def(),
}
wildcard_suffix_tag_no_match {
args: func_args![value: value!({"tags": ["b:vector"]}), query: "a:vec*"],
want: Ok(false),
tdef: type_def(),
}
not_wildcard_suffix_tag_no_match {
args: func_args![value: value!({"tags": ["b:vector"]}), query: "NOT a:vec*"],
want: Ok(true),
tdef: type_def(),
}
negate_wildcard_suffix_tag_no_match {
args: func_args![value: value!({"tags": ["b:vector"]}), query: "-a:vec*"],
want: Ok(true),
tdef: type_def(),
}
wildcard_suffix_facet {
args: func_args![value: value!({"a": "vector"}), query: "@a:vec*"],
want: Ok(true),
tdef: type_def(),
}
not_wildcard_suffix_facet {
args: func_args![value: value!({"a": "vector"}), query: "NOT @a:vec*"],
want: Ok(false),
tdef: type_def(),
}
negate_wildcard_suffix_facet {
args: func_args![value: value!({"a": "vector"}), query: "-@a:vec*"],
want: Ok(false),
tdef: type_def(),
}
wildcard_suffix_facet_no_match {
args: func_args![value: value!({"b": "vector"}), query: "@a:vec*"],
want: Ok(false),
tdef: type_def(),
}
not_wildcard_suffix_facet_no_match {
args: func_args![value: value!({"b": "vector"}), query: "NOT @a:vec*"],
want: Ok(true),
tdef: type_def(),
}
negate_wildcard_suffix_facet_no_match {
args: func_args![value: value!({"b": "vector"}), query: "-@a:vec*"],
want: Ok(true),
tdef: type_def(),
}
wildcard_multiple_message {
args: func_args![value: value!({"message": "vector"}), query: "v*c*r"],
want: Ok(true),
tdef: type_def(),
}
not_wildcard_multiple_message {
args: func_args![value: value!({"message": "vector"}), query: "NOT v*c*r"],
want: Ok(false),
tdef: type_def(),
}
negate_wildcard_multiple_message {
args: func_args![value: value!({"message": "vector"}), query: "-v*c*r"],
want: Ok(false),
tdef: type_def(),
}
wildcard_multiple_message_no_match {
args: func_args![value: value!({"message": "torvec"}), query: "v*c*r"],
want: Ok(false),
tdef: type_def(),
}
not_wildcard_multiple_message_no_match {
args: func_args![value: value!({"message": "torvec"}), query: "NOT v*c*r"],
want: Ok(true),
tdef: type_def(),
}
negate_wildcard_multiple_message_no_match {
args: func_args![value: value!({"message": "torvec"}), query: "-v*c*r"],
want: Ok(true),
tdef: type_def(),
}
wildcard_multiple_tag {
args: func_args![value: value!({"tags": ["a:vector"]}), query: "a:v*c*r"],
want: Ok(true),
tdef: type_def(),
}
not_wildcard_multiple_tag {
args: func_args![value: value!({"tags": ["a:vector"]}), query: "NOT a:v*c*r"],
want: Ok(false),
tdef: type_def(),
}
negate_wildcard_multiple_tag {
args: func_args![value: value!({"tags": ["a:vector"]}), query: "-a:v*c*r"],
want: Ok(false),
tdef: type_def(),
}
wildcard_multiple_tag_no_match {
args: func_args![value: value!({"tags": ["b:vector"]}), query: "a:v*c*r"],
want: Ok(false),
tdef: type_def(),
}
not_wildcard_multiple_tag_no_match {
args: func_args![value: value!({"tags": ["b:vector"]}), query: "NOT a:v*c*r"],
want: Ok(true),
tdef: type_def(),
}
negate_wildcard_multiple_tag_no_match {
args: func_args![value: value!({"tags": ["b:vector"]}), query: "-a:v*c*r"],
want: Ok(true),
tdef: type_def(),
}
wildcard_multiple_facet {
args: func_args![value: value!({"a": "vector"}), query: "@a:v*c*r"],
want: Ok(true),
tdef: type_def(),
}
not_wildcard_multiple_facet {
args: func_args![value: value!({"a": "vector"}), query: "NOT @a:v*c*r"],
want: Ok(false),
tdef: type_def(),
}
negate_wildcard_multiple_facet {
args: func_args![value: value!({"a": "vector"}), query: "-@a:v*c*r"],
want: Ok(false),
tdef: type_def(),
}
wildcard_multiple_facet_no_match {
args: func_args![value: value!({"b": "vector"}), query: "@a:v*c*r"],
want: Ok(false),
tdef: type_def(),
}
not_wildcard_multiple_facet_no_match {
args: func_args![value: value!({"b": "vector"}), query: "NOT @a:v*c*r"],
want: Ok(true),
tdef: type_def(),
}
negate_wildcard_multiple_facet_no_match {
args: func_args![value: value!({"b": "vector"}), query: "-@a:v*c*r"],
want: Ok(true),
tdef: type_def(),
}
range_message_unbounded {
args: func_args![value: value!({"message": "1"}), query: "[* TO *]"],
want: Ok(true),
tdef: type_def(),
}
not_range_message_unbounded {
args: func_args![value: value!({"message": "1"}), query: "NOT [* TO *]"],
want: Ok(false),
tdef: type_def(),
}
negate_range_message_unbounded {
args: func_args![value: value!({"message": "1"}), query: "-[* TO *]"],
want: Ok(false),
tdef: type_def(),
}
range_message_lower_bound {
args: func_args![value: value!({"message": "400"}), query: "[4 TO *]"],
want: Ok(true),
tdef: type_def(),
}
not_range_message_lower_bound {
args: func_args![value: value!({"message": "400"}), query: "NOT [4 TO *]"],
want: Ok(false),
tdef: type_def(),
}
negate_range_message_lower_bound {
args: func_args![value: value!({"message": "400"}), query: "-[4 TO *]"],
want: Ok(false),
tdef: type_def(),
}
range_message_lower_bound_no_match {
args: func_args![value: value!({"message": "400"}), query: "[50 TO *]"],
want: Ok(false),
tdef: type_def(),
}
not_range_message_lower_bound_no_match {
args: func_args![value: value!({"message": "400"}), query: "NOT [50 TO *]"],
want: Ok(true),
tdef: type_def(),
}
negate_range_message_lower_bound_no_match {
args: func_args![value: value!({"message": "400"}), query: "-[50 TO *]"],
want: Ok(true),
tdef: type_def(),
}
range_message_lower_bound_string {
args: func_args![value: value!({"message": "400"}), query: r#"["4" TO *]"#],
want: Ok(true),
tdef: type_def(),
}
not_range_message_lower_bound_string {
args: func_args![value: value!({"message": "400"}), query: r#"NOT ["4" TO *]"#],
want: Ok(false),
tdef: type_def(),
}
negate_range_message_lower_bound_string {
args: func_args![value: value!({"message": "400"}), query: r#"-["4" TO *]"#],
want: Ok(false),
tdef: type_def(),
}
range_message_lower_bound_string_no_match {
args: func_args![value: value!({"message": "400"}), query: r#"["50" TO *]"#],
want: Ok(false),
tdef: type_def(),
}
not_range_message_lower_bound_string_no_match {
args: func_args![value: value!({"message": "400"}), query: r#"NOT ["50" TO *]"#],
want: Ok(true),
tdef: type_def(),
}
negate_range_message_lower_bound_string_no_match {
args: func_args![value: value!({"message": "400"}), query: r#"-["50" TO *]"#],
want: Ok(true),
tdef: type_def(),
}
range_message_upper_bound {
args: func_args![value: value!({"message": "300"}), query: "[* TO 4]"],
want: Ok(true),
tdef: type_def(),
}
not_range_message_upper_bound {
args: func_args![value: value!({"message": "300"}), query: "NOT [* TO 4]"],
want: Ok(false),
tdef: type_def(),
}
negate_range_message_upper_bound {
args: func_args![value: value!({"message": "300"}), query: "-[* TO 4]"],
want: Ok(false),
tdef: type_def(),
}
range_message_upper_bound_no_match {
args: func_args![value: value!({"message": "50"}), query: "[* TO 400]"],
want: Ok(false),
tdef: type_def(),
}
not_range_message_upper_bound_no_match {
args: func_args![value: value!({"message": "50"}), query: "NOT [* TO 400]"],
want: Ok(true),
tdef: type_def(),
}
negate_range_message_upper_bound_no_match {
args: func_args![value: value!({"message": "50"}), query: "-[* TO 400]"],
want: Ok(true),
tdef: type_def(),
}
range_message_upper_bound_string {
args: func_args![value: value!({"message": "300"}), query: r#"[* TO "4"]"#],
want: Ok(true),
tdef: type_def(),
}
not_range_message_upper_bound_string {
args: func_args![value: value!({"message": "300"}), query: r#"NOT [* TO "4"]"#],
want: Ok(false),
tdef: type_def(),
}
negate_range_message_upper_bound_string {
args: func_args![value: value!({"message": "300"}), query: r#"-[* TO "4"]"#],
want: Ok(false),
tdef: type_def(),
}
range_message_upper_bound_string_no_match {
args: func_args![value: value!({"message": "50"}), query: r#"[* TO "400"]"#],
want: Ok(false),
tdef: type_def(),
}
not_range_message_upper_bound_string_no_match {
args: func_args![value: value!({"message": "50"}), query: r#"NOT [* TO "400"]"#],
want: Ok(true),
tdef: type_def(),
}
negate_range_message_upper_bound_string_no_match {
args: func_args![value: value!({"message": "50"}), query: r#"NOT [* TO "400"]"#],
want: Ok(true),
tdef: type_def(),
}
range_message_between {
args: func_args![value: value!({"message": 500}), query: "[1 TO 6]"],
want: Ok(true),
tdef: type_def(),
}
not_range_message_between {
args: func_args![value: value!({"message": 500}), query: "NOT [1 TO 6]"],
want: Ok(false),
tdef: type_def(),
}
negate_range_message_between {
args: func_args![value: value!({"message": 500}), query: "-[1 TO 6]"],
want: Ok(false),
tdef: type_def(),
}
range_message_between_no_match {
args: func_args![value: value!({"message": 70}), query: "[1 TO 6]"],
want: Ok(false),
tdef: type_def(),
}
not_range_message_between_no_match {
args: func_args![value: value!({"message": 70}), query: "NOT [1 TO 6]"],
want: Ok(true),
tdef: type_def(),
}
negate_range_message_between_no_match {
args: func_args![value: value!({"message": 70}), query: "-[1 TO 6]"],
want: Ok(true),
tdef: type_def(),
}
range_message_between_string {
args: func_args![value: value!({"message": "500"}), query: r#"["1" TO "6"]"#],
want: Ok(true),
tdef: type_def(),
}
not_range_message_between_string {
args: func_args![value: value!({"message": "500"}), query: r#"NOT ["1" TO "6"]"#],
want: Ok(false),
tdef: type_def(),
}
negate_range_message_between_string {
args: func_args![value: value!({"message": "500"}), query: r#"-["1" TO "6"]"#],
want: Ok(false),
tdef: type_def(),
}
range_message_between_no_match_string {
args: func_args![value: value!({"message": "70"}), query: r#"["1" TO "6"]"#],
want: Ok(false),
tdef: type_def(),
}
not_range_message_between_no_match_string {
args: func_args![value: value!({"message": "70"}), query: r#"NOT ["1" TO "6"]"#],
want: Ok(true),
tdef: type_def(),
}
negate_range_message_between_no_match_string {
args: func_args![value: value!({"message": "70"}), query: r#"-["1" TO "6"]"#],
want: Ok(true),
tdef: type_def(),
}
range_tag_key {
args: func_args![value: value!({"tags": ["a"]}), query: "a:[* TO *]"],
want: Ok(true),
tdef: type_def(),
}
range_tag_key_no_match {
args: func_args![value: value!({"tags": ["b"]}), query: "a:[* TO *]"],
want: Ok(false),
tdef: type_def(),
}
range_tag_unbounded {
args: func_args![value: value!({"tags": ["a:1"]}), query: "a:[* TO *]"],
want: Ok(true),
tdef: type_def(),
}
not_range_tag_unbounded {
args: func_args![value: value!({"tags": ["a:1"]}), query: "NOT a:[* TO *]"],
want: Ok(false),
tdef: type_def(),
}
negate_range_tag_unbounded {
args: func_args![value: value!({"tags": ["a:1"]}), query: "-a:[* TO *]"],
want: Ok(false),
tdef: type_def(),
}
range_tag_lower_bound {
args: func_args![value: value!({"tags": ["a:400"]}), query: "a:[4 TO *]"],
want: Ok(true),
tdef: type_def(),
}
not_range_tag_lower_bound {
args: func_args![value: value!({"tags": ["a:400"]}), query: "NOT a:[4 TO *]"],
want: Ok(false),
tdef: type_def(),
}
negate_range_tag_lower_bound {
args: func_args![value: value!({"tags": ["a:400"]}), query: "-a:[4 TO *]"],
want: Ok(false),
tdef: type_def(),
}
range_tag_lower_bound_no_match {
args: func_args![value: value!({"tags": ["a:400"]}), query: "a:[50 TO *]"],
want: Ok(false),
tdef: type_def(),
}
not_range_tag_lower_bound_no_match {
args: func_args![value: value!({"tags": ["a:400"]}), query: "NOT a:[50 TO *]"],
want: Ok(true),
tdef: type_def(),
}
negate_range_tag_lower_bound_no_match {
args: func_args![value: value!({"tags": ["a:400"]}), query: "-a:[50 TO *]"],
want: Ok(true),
tdef: type_def(),
}
range_tag_lower_bound_string {
args: func_args![value: value!({"tags": ["a:400"]}), query: r#"a:["4" TO *]"#],
want: Ok(true),
tdef: type_def(),
}
not_range_tag_lower_bound_string {
args: func_args![value: value!({"tags": ["a:400"]}), query: r#"NOT a:["4" TO *]"#],
want: Ok(false),
tdef: type_def(),
}
negate_range_tag_lower_bound_string {
args: func_args![value: value!({"tags": ["a:400"]}), query: r#"-a:["4" TO *]"#],
want: Ok(false),
tdef: type_def(),
}
range_tag_lower_bound_string_no_match {
args: func_args![value: value!({"tags": ["a:400"]}), query: r#"a:["50" TO *]"#],
want: Ok(false),
tdef: type_def(),
}
not_range_tag_lower_bound_string_no_match {
args: func_args![value: value!({"tags": ["a:400"]}), query: r#"NOT a:["50" TO *]"#],
want: Ok(true),
tdef: type_def(),
}
negate_range_tag_lower_bound_string_no_match {
args: func_args![value: value!({"tags": ["a:400"]}), query: r#"-a:["50" TO *]"#],
want: Ok(true),
tdef: type_def(),
}
range_tag_upper_bound {
args: func_args![value: value!({"tags": ["a:300"]}), query: "a:[* TO 4]"],
want: Ok(true),
tdef: type_def(),
}
not_range_tag_upper_bound {
args: func_args![value: value!({"tags": ["a:300"]}), query: "NOT a:[* TO 4]"],
want: Ok(false),
tdef: type_def(),
}
negate_range_tag_upper_bound {
args: func_args![value: value!({"tags": ["a:300"]}), query: "-a:[* TO 4]"],
want: Ok(false),
tdef: type_def(),
}
range_tag_upper_bound_no_match {
args: func_args![value: value!({"tags": ["a:50"]}), query: "a:[* TO 400]"],
want: Ok(false),
tdef: type_def(),
}
not_range_tag_upper_bound_no_match {
args: func_args![value: value!({"tags": ["a:50"]}), query: "NOT a:[* TO 400]"],
want: Ok(true),
tdef: type_def(),
}
negate_range_tag_upper_bound_no_match {
args: func_args![value: value!({"tags": ["a:50"]}), query: "-a:[* TO 400]"],
want: Ok(true),
tdef: type_def(),
}
range_tag_upper_bound_string {
args: func_args![value: value!({"tags": ["a:300"]}), query: r#"a:[* TO "4"]"#],
want: Ok(true),
tdef: type_def(),
}
not_range_tag_upper_bound_string {
args: func_args![value: value!({"tags": ["a:300"]}), query: r#"NOT a:[* TO "4"]"#],
want: Ok(false),
tdef: type_def(),
}
negate_range_tag_upper_bound_string {
args: func_args![value: value!({"tags": ["a:300"]}), query: r#"-a:[* TO "4"]"#],
want: Ok(false),
tdef: type_def(),
}
range_tag_upper_bound_string_no_match {
args: func_args![value: value!({"tags": ["a:50"]}), query: r#"a:[* TO "400"]"#],
want: Ok(false),
tdef: type_def(),
}
not_range_tag_upper_bound_string_no_match {
args: func_args![value: value!({"tags": ["a:50"]}), query: r#"NOT a:[* TO "400"]"#],
want: Ok(true),
tdef: type_def(),
}
negate_range_tag_upper_bound_string_no_match {
args: func_args![value: value!({"tags": ["a:50"]}), query: r#"-a:[* TO "400"]"#],
want: Ok(true),
tdef: type_def(),
}
range_tag_between {
args: func_args![value: value!({"tags": ["a:500"]}), query: "a:[1 TO 6]"],
want: Ok(true),
tdef: type_def(),
}
not_range_tag_between {
args: func_args![value: value!({"tags": ["a:500"]}), query: "NOT a:[1 TO 6]"],
want: Ok(false),
tdef: type_def(),
}
negate_range_tag_between {
args: func_args![value: value!({"tags": ["a:500"]}), query: "-a:[1 TO 6]"],
want: Ok(false),
tdef: type_def(),
}
range_tag_between_no_match {
args: func_args![value: value!({"tags": ["a:70"]}), query: "a:[1 TO 6]"],
want: Ok(false),
tdef: type_def(),
}
not_range_tag_between_no_match {
args: func_args![value: value!({"tags": ["a:70"]}), query: "NOT a:[1 TO 6]"],
want: Ok(true),
tdef: type_def(),
}
negate_range_tag_between_no_match {
args: func_args![value: value!({"tags": ["a:70"]}), query: "-a:[1 TO 6]"],
want: Ok(true),
tdef: type_def(),
}
range_tag_between_string {
args: func_args![value: value!({"tags": ["a:500"]}), query: r#"a:["1" TO "6"]"#],
want: Ok(true),
tdef: type_def(),
}
not_range_tag_between_string {
args: func_args![value: value!({"tags": ["a:500"]}), query: r#"NOT a:["1" TO "6"]"#],
want: Ok(false),
tdef: type_def(),
}
negate_range_tag_between_string {
args: func_args![value: value!({"tags": ["a:500"]}), query: r#"-a:["1" TO "6"]"#],
want: Ok(false),
tdef: type_def(),
}
range_tag_between_no_match_string {
args: func_args![value: value!({"tags": ["a:70"]}), query: r#"a:["1" TO "6"]"#],
want: Ok(false),
tdef: type_def(),
}
not_range_tag_between_no_match_string {
args: func_args![value: value!({"tags": ["a:70"]}), query: r#"NOT a:["1" TO "6"]"#],
want: Ok(true),
tdef: type_def(),
}
negate_range_tag_between_no_match_string {
args: func_args![value: value!({"tags": ["a:70"]}), query: r#"-a:["1" TO "6"]"#],
want: Ok(true),
tdef: type_def(),
}
range_facet_unbounded {
args: func_args![value: value!({"a": 1}), query: "@a:[* TO *]"],
want: Ok(true),
tdef: type_def(),
}
not_range_facet_unbounded {
args: func_args![value: value!({"a": 1}), query: "NOT @a:[* TO *]"],
want: Ok(false),
tdef: type_def(),
}
negate_range_facet_unbounded {
args: func_args![value: value!({"a": 1}), query: "-@a:[* TO *]"],
want: Ok(false),
tdef: type_def(),
}
range_facet_lower_bound {
args: func_args![value: value!({"a": 5}), query: "@a:[4 TO *]"],
want: Ok(true),
tdef: type_def(),
}
not_range_facet_lower_bound {
args: func_args![value: value!({"a": 5}), query: "NOT @a:[4 TO *]"],
want: Ok(false),
tdef: type_def(),
}
negate_range_facet_lower_bound {
args: func_args![value: value!({"a": 5}), query: "-@a:[4 TO *]"],
want: Ok(false),
tdef: type_def(),
}
range_facet_lower_bound_no_match {
args: func_args![value: value!({"a": 5}), query: "@a:[50 TO *]"],
want: Ok(false),
tdef: type_def(),
}
not_range_facet_lower_bound_no_match {
args: func_args![value: value!({"a": 5}), query: "NOT @a:[50 TO *]"],
want: Ok(true),
tdef: type_def(),
}
negate_range_facet_lower_bound_no_match {
args: func_args![value: value!({"a": 5}), query: "-@a:[50 TO *]"],
want: Ok(true),
tdef: type_def(),
}
range_facet_lower_bound_string {
args: func_args![value: value!({"a": "5"}), query: r#"@a:["4" TO *]"#],
want: Ok(true),
tdef: type_def(),
}
not_range_facet_lower_bound_string {
args: func_args![value: value!({"a": "5"}), query: r#"NOT @a:["4" TO *]"#],
want: Ok(false),
tdef: type_def(),
}
negate_range_facet_lower_bound_string {
args: func_args![value: value!({"a": "5"}), query: r#"-@a:["4" TO *]"#],
want: Ok(false),
tdef: type_def(),
}
range_facet_lower_bound_string_no_match {
args: func_args![value: value!({"a": "400"}), query: r#"@a:["50" TO *]"#],
want: Ok(false),
tdef: type_def(),
}
not_range_facet_lower_bound_string_no_match {
args: func_args![value: value!({"a": "400"}), query: r#"NOT @a:["50" TO *]"#],
want: Ok(true),
tdef: type_def(),
}
negate_range_facet_lower_bound_string_no_match {
args: func_args![value: value!({"a": "400"}), query: r#"-@a:["50" TO *]"#],
want: Ok(true),
tdef: type_def(),
}
range_facet_upper_bound {
args: func_args![value: value!({"a": 1}), query: "@a:[* TO 4]"],
want: Ok(true),
tdef: type_def(),
}
not_range_facet_upper_bound {
args: func_args![value: value!({"a": 1}), query: "NOT @a:[* TO 4]"],
want: Ok(false),
tdef: type_def(),
}
negate_range_facet_upper_bound {
args: func_args![value: value!({"a": 1}), query: "-@a:[* TO 4]"],
want: Ok(false),
tdef: type_def(),
}
range_facet_upper_bound_no_match {
args: func_args![value: value!({"a": 500}), query: "@a:[* TO 400]"],
want: Ok(false),
tdef: type_def(),
}
not_range_facet_upper_bound_no_match {
args: func_args![value: value!({"a": 500}), query: "NOT @a:[* TO 400]"],
want: Ok(true),
tdef: type_def(),
}
negate_range_facet_upper_bound_no_match {
args: func_args![value: value!({"a": 500}), query: "-@a:[* TO 400]"],
want: Ok(true),
tdef: type_def(),
}
range_facet_upper_bound_string {
args: func_args![value: value!({"a": "3"}), query: r#"@a:[* TO "4"]"#],
want: Ok(true),
tdef: type_def(),
}
not_range_facet_upper_bound_string {
args: func_args![value: value!({"a": "3"}), query: r#"NOT @a:[* TO "4"]"#],
want: Ok(false),
tdef: type_def(),
}
negate_range_facet_upper_bound_string {
args: func_args![value: value!({"a": "3"}), query: r#"-@a:[* TO "4"]"#],
want: Ok(false),
tdef: type_def(),
}
range_facet_upper_bound_string_no_match {
args: func_args![value: value!({"a": "5"}), query: r#"@a:[* TO "400"]"#],
want: Ok(false),
tdef: type_def(),
}
not_range_facet_upper_bound_string_no_match {
args: func_args![value: value!({"a": "5"}), query: r#"NOT @a:[* TO "400"]"#],
want: Ok(true),
tdef: type_def(),
}
negate_range_facet_upper_bound_string_no_match {
args: func_args![value: value!({"a": "5"}), query: r#"-@a:[* TO "400"]"#],
want: Ok(true),
tdef: type_def(),
}
range_facet_between {
args: func_args![value: value!({"a": 5}), query: "@a:[1 TO 6]"],
want: Ok(true),
tdef: type_def(),
}
not_range_facet_between {
args: func_args![value: value!({"a": 5}), query: "NOT @a:[1 TO 6]"],
want: Ok(false),
tdef: type_def(),
}
negate_range_facet_between {
args: func_args![value: value!({"a": 5}), query: "-@a:[1 TO 6]"],
want: Ok(false),
tdef: type_def(),
}
range_facet_between_no_match {
args: func_args![value: value!({"a": 200}), query: "@a:[1 TO 6]"],
want: Ok(false),
tdef: type_def(),
}
not_range_facet_between_no_match {
args: func_args![value: value!({"a": 200}), query: "NOT @a:[1 TO 6]"],
want: Ok(true),
tdef: type_def(),
}
negate_range_facet_between_no_match {
args: func_args![value: value!({"a": 200}), query: "-@a:[1 TO 6]"],
want: Ok(true),
tdef: type_def(),
}
range_facet_between_string {
args: func_args![value: value!({"a": "500"}), query: r#"@a:["1" TO "6"]"#],
want: Ok(true),
tdef: type_def(),
}
not_range_facet_between_string {
args: func_args![value: value!({"a": "500"}), query: r#"NOT @a:["1" TO "6"]"#],
want: Ok(false),
tdef: type_def(),
}
negate_range_facet_between_string {
args: func_args![value: value!({"a": "500"}), query: r#"-@a:["1" TO "6"]"#],
want: Ok(false),
tdef: type_def(),
}
range_facet_between_no_match_string {
args: func_args![value: value!({"a": "7"}), query: r#"@a:["1" TO "60"]"#],
want: Ok(false),
tdef: type_def(),
}
not_range_facet_between_no_match_string {
args: func_args![value: value!({"a": "7"}), query: r#"NOT @a:["1" TO "60"]"#],
want: Ok(true),
tdef: type_def(),
}
negate_range_facet_between_no_match_string {
args: func_args![value: value!({"a": "7"}), query: r#"-@a:["1" TO "60"]"#],
want: Ok(true),
tdef: type_def(),
}
exclusive_range_message {
args: func_args![value: value!({"message": "100"}), query: "{1 TO 2}"],
want: Ok(true),
tdef: type_def(),
}
not_exclusive_range_message {
args: func_args![value: value!({"message": "100"}), query: "NOT {1 TO 2}"],
want: Ok(false),
tdef: type_def(),
}
negate_exclusive_range_message {
args: func_args![value: value!({"message": "100"}), query: "-{1 TO 2}"],
want: Ok(false),
tdef: type_def(),
}
exclusive_range_message_no_match {
args: func_args![value: value!({"message": "1"}), query: "{1 TO 2}"],
want: Ok(false),
tdef: type_def(),
}
not_exclusive_range_message_no_match {
args: func_args![value: value!({"message": "1"}), query: "NOT {1 TO 2}"],
want: Ok(true),
tdef: type_def(),
}
negate_exclusive_range_message_no_match {
args: func_args![value: value!({"message": "1"}), query: "-{1 TO 2}"],
want: Ok(true),
tdef: type_def(),
}
exclusive_range_message_lower {
args: func_args![value: value!({"message": "200"}), query: "{1 TO *}"],
want: Ok(true),
tdef: type_def(),
}
not_exclusive_range_message_lower {
args: func_args![value: value!({"message": "200"}), query: "NOT {1 TO *}"],
want: Ok(false),
tdef: type_def(),
}
negate_exclusive_range_message_lower {
args: func_args![value: value!({"message": "200"}), query: "-{1 TO *}"],
want: Ok(false),
tdef: type_def(),
}
exclusive_range_message_lower_no_match {
args: func_args![value: value!({"message": "1"}), query: "{1 TO *}"],
want: Ok(false),
tdef: type_def(),
}
not_exclusive_range_message_lower_no_match {
args: func_args![value: value!({"message": "1"}), query: "NOT {1 TO *}"],
want: Ok(true),
tdef: type_def(),
}
negate_exclusive_range_message_lower_no_match {
args: func_args![value: value!({"message": "1"}), query: "-{1 TO *}"],
want: Ok(true),
tdef: type_def(),
}
exclusive_range_message_upper {
args: func_args![value: value!({"message": "200"}), query: "{* TO 3}"],
want: Ok(true),
tdef: type_def(),
}
not_exclusive_range_message_upper {
args: func_args![value: value!({"message": "200"}), query: "NOT {* TO 3}"],
want: Ok(false),
tdef: type_def(),
}
negate_exclusive_range_message_upper {
args: func_args![value: value!({"message": "200"}), query: "-{* TO 3}"],
want: Ok(false),
tdef: type_def(),
}
exclusive_range_message_upper_no_match {
args: func_args![value: value!({"message": "3"}), query: "{* TO 3}"],
want: Ok(false),
tdef: type_def(),
}
not_exclusive_range_message_upper_no_match {
args: func_args![value: value!({"message": "3"}), query: "NOT {* TO 3}"],
want: Ok(true),
tdef: type_def(),
}
negate_exclusive_range_message_upper_no_match {
args: func_args![value: value!({"message": "3"}), query: "-{* TO 3}"],
want: Ok(true),
tdef: type_def(),
}
message_and {
args: func_args![value: value!({"message": "this contains that"}), query: "this AND that"],
want: Ok(true),
tdef: type_def(),
}
message_and_not {
args: func_args![value: value!({"message": "this contains that"}), query: "this AND NOT that"],
want: Ok(false),
tdef: type_def(),
}
message_or {
args: func_args![value: value!({"message": "only contains that"}), query: "this OR that"],
want: Ok(true),
tdef: type_def(),
}
message_or_not {
args: func_args![value: value!({"message": "only contains that"}), query: "this OR NOT that"],
want: Ok(false),
tdef: type_def(),
}
message_and_or {
args: func_args![value: value!({"message": "this contains that"}), query: "this AND (that OR the_other)"],
want: Ok(true),
tdef: type_def(),
}
not_message_and_or {
args: func_args![value: value!({"message": "this contains that"}), query: "this AND NOT (that OR the_other)"],
want: Ok(false),
tdef: type_def(),
}
negate_message_and_or {
args: func_args![value: value!({"message": "this contains that"}), query: "this AND -(that OR the_other)"],
want: Ok(false),
tdef: type_def(),
}
message_and_or_2 {
args: func_args![value: value!({"message": "this contains the_other"}), query: "this AND (that OR the_other)"],
want: Ok(true),
tdef: type_def(),
}
not_message_and_or_2 {
args: func_args![value: value!({"message": "this contains the_other"}), query: "this AND NOT (that OR the_other)"],
want: Ok(false),
tdef: type_def(),
}
negate_message_and_or_2 {
args: func_args![value: value!({"message": "this contains the_other"}), query: "this AND -(that OR the_other)"],
want: Ok(false),
tdef: type_def(),
}
message_or_and {
args: func_args![value: value!({"message": "just this"}), query: "this OR (that AND the_other)"],
want: Ok(true),
tdef: type_def(),
}
message_or_and_no_match {
args: func_args![value: value!({"message": "that and nothing else"}), query: "this OR (that AND the_other)"],
want: Ok(false),
tdef: type_def(),
}
message_or_and_2 {
args: func_args![value: value!({"message": "that plus the_other"}), query: "this OR (that AND the_other)"],
want: Ok(true),
tdef: type_def(),
}
message_or_and_2_no_match {
args: func_args![value: value!({"message": "nothing plus the_other"}), query: "this OR (that AND the_other)"],
want: Ok(false),
tdef: type_def(),
}
kitchen_sink {
args: func_args![value: value!({"host": "this"}), query: "host:this OR ((@b:test* AND c:that) AND d:the_other @e:[1 TO 5])"],
want: Ok(true),
tdef: type_def(),
}
kitchen_sink_2 {
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])"],
want: Ok(true),
tdef: type_def(),
}
integer_range_float_value_match {
args: func_args![value: value!({"level": 7.0}), query: "@level:[7 TO 10]"],
want: Ok(true),
tdef: type_def(),
}
integer_range_float_value_no_match {
args: func_args![value: value!({"level": 6.9}), query: "@level:[7 TO 10]"],
want: Ok(false),
tdef: type_def(),
}
float_range_integer_value_match {
args: func_args![value: value!({"level": 7}), query: "@level:[7.0 TO 10.0]"],
want: Ok(true),
tdef: type_def(),
}
float_range_integer_value_no_match {
args: func_args![value: value!({"level": 6}), query: "@level:[7.0 TO 10.0]"],
want: Ok(false),
tdef: type_def(),
}
path_parser_hyphen {
args: func_args![value: value!({"a-b": "3"}), query: "@a-b:3"],
want: Ok(true),
tdef: type_def(),
}
path_parser_failure {
args: func_args![value: value!({"a-b": "3"}), query: "@a%:3"],
want: Err("invalid argument"),
tdef: type_def(),
}
quoted_query_key_match {
args: func_args![value: value!({"a-b": 1}), query: "@\\\"a-b\\\":1"],
want: Ok(true),
tdef: type_def(),
}
];
}