Skip to content

Commit

Permalink
feat: support bool match
Browse files Browse the repository at this point in the history
  • Loading branch information
qjerome committed Nov 13, 2024
1 parent d3af8d9 commit d5b7b59
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
2 changes: 1 addition & 1 deletion gene/src/rules/grammars/match.pest
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ field_path = ${ sep ~ ("\"" ~ segment_with_ws ~ "\"" | segment) ~ field_pat

value_dq = _{ "\"" ~ (!("\"") ~ ANY)* ~ "\"" }
value_sq = _{ "'" ~ (!("'") ~ ANY)* ~ "'" }
value = @{ (value_dq | value_sq | "none" | "some") }
value = @{ (value_dq | value_sq | "none" | "some" | "true" | "false") }

// the order in which operators are evaluated is important
op = _{ eq | lte | lt | gte | gt | rex | flag }
Expand Down
29 changes: 28 additions & 1 deletion gene/src/rules/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pub(crate) enum MatchValue {
Number(Number),
StringOrNumber(String, Number),
Regex(Regex),
Bool(bool),
Some,
None,
}
Expand All @@ -72,6 +73,7 @@ impl MatchValue {
Self::Number(_) => "number",
Self::StringOrNumber(_, _) => "string_or_number",
Self::Regex(_) => "regex",
Self::Bool(_) => "bool",
Self::Some => "some",
Self::None => "none",
}
Expand Down Expand Up @@ -226,11 +228,13 @@ impl FromStr for DirectMatch {

let rule_op = inner_pairs.next().unwrap().as_rule();

// easier to trim quotes here rather than walking parsed items
let str_value = inner_pairs.next().unwrap().as_str();
let is_none = str_value == "none";
let is_some = str_value == "some";
let is_bool_true = str_value.to_lowercase() == "true";
let is_bool_false = str_value.to_lowercase() == "false";

// easier to trim quotes here rather than walking parsed items
let sanit_value = str_value.trim_matches('\'').trim_matches('"');

let (op, value) = match rule_op {
Expand All @@ -239,6 +243,10 @@ impl FromStr for DirectMatch {
MatchValue::None
} else if is_some {
MatchValue::Some
} else if is_bool_true {
MatchValue::Bool(true)
} else if is_bool_false {
MatchValue::Bool(false)
} else if let Ok(i) = Number::from_str(sanit_value) {
// handle the case where string can also be an
// integer. Number::from_str manages hex prefix
Expand Down Expand Up @@ -277,6 +285,7 @@ macro_rules! cmp_values {
}

impl DirectMatch {
#[inline]
pub(crate) fn match_event<E: Event>(&self, event: &E) -> Result<bool, Error> {
if let Some(fvalue) = event.get_from_path(&self.field_path) {
return self
Expand All @@ -292,6 +301,7 @@ impl DirectMatch {
))
}

#[inline]
pub(crate) fn match_value(&self, tgt: &FieldValue) -> Result<bool, ()> {
// we handle a special case where we expect to match a number and the field is a string
// in this case we attempt to convert the string value into a number. Mostly because
Expand Down Expand Up @@ -333,6 +343,13 @@ impl DirectMatch {
Err(())
},
)
.or(
if let (FieldValue::Bool(fvb), MatchValue::Bool(mvb)) = (&fv, &(self.value)) {
Ok(fvb == mvb)
} else {
Err(())
},
)
.or(
// we return Ok only if we want to match some
if matches!(self.value, MatchValue::Some) {
Expand Down Expand Up @@ -431,6 +448,16 @@ mod test {
.match_value(&FieldValue::None)
.unwrap());

assert!(DirectMatch::from_str(r#".data is true"#)
.unwrap()
.match_value(&FieldValue::Bool(true))
.unwrap());

assert!(DirectMatch::from_str(r#".data is false"#)
.unwrap()
.match_value(&FieldValue::Bool(false))
.unwrap());

// we try to match None against a string so we must return an error
assert!(DirectMatch::from_str(r#".data is 'toast'"#)
.unwrap()
Expand Down

0 comments on commit d5b7b59

Please sign in to comment.