Skip to content

Commit

Permalink
Merge pull request #3 from kunai-project/pr-impl-some-value
Browse files Browse the repository at this point in the history
Pr impl some value
  • Loading branch information
qjerome authored Jul 16, 2024
2 parents 36503c2 + 2a1f908 commit f6bab0d
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 13 deletions.
6 changes: 5 additions & 1 deletion derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,11 @@ impl FieldGetterDerive {
impl #generics FieldGetter for #struct_name #generics #generic_trait_bound{
#[inline(always)]
fn get_from_iter(&self, mut i: core::slice::Iter<'_, std::string::String>) -> Option<FieldValue> {
let field = i.next()?;

let field = match i.next() {
Some(s) => s,
None => return Some(FieldValue::Some),
};

match field.as_str() {
#(#arms)*
Expand Down
14 changes: 11 additions & 3 deletions gene/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ where
fn get_from_iter(&self, i: core::slice::Iter<'_, std::string::String>) -> Option<FieldValue> {
match self {
Some(v) => v.get_from_iter(i),
None => None,
None => Some(FieldValue::None),
}
}
}
Expand All @@ -103,7 +103,11 @@ where
&self,
mut i: core::slice::Iter<'_, std::string::String>,
) -> Option<FieldValue> {
let k = i.next()?;
let k = match i.next() {
Some(s) => s,
None => return Some(FieldValue::Some),
};

if i.len() > 0 {
return None;
}
Expand Down Expand Up @@ -238,10 +242,14 @@ mod test {
Some("some_id".into())
);

assert!(event.get_from_path(&path!(".data")).is_none());
assert_eq!(
event.get_from_path(&path!(".data.some_value")),
Some(1u64.into())
);

// if value is not known, it must at least return FieldValue::Some
assert!(event.get_from_path(&path!(".data")).is_some());
// None must be returned if trying to get a non existing field
assert!(event.get_from_path(&path!(".unknown")).is_none());
}
}
2 changes: 1 addition & 1 deletion gene/src/rules/condition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ mod tests {
let bad = ["a", "$a b", "$a-t"];

bad.iter().for_each(|ident| {
if ConditionParser::parse(Rule::_ident_test, ident).is_ok() {
if ConditionParser::parse(Rule::condition, ident).is_ok() {
panic!("{ident} should produce an error")
}
});
Expand Down
3 changes: 1 addition & 2 deletions gene/src/rules/grammars/condition.pest
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
ident = @{ "$" ~ (ASCII_ALPHANUMERIC | "_")+ }
_ident_test = _{ SOI ~ expr ~ EOI }
ident = @{ "$" ~ (ASCII_ALPHANUMERIC | "_")+ }

negate = { ("!" | "not") }
op = _{ or | and }
Expand Down
4 changes: 2 additions & 2 deletions gene/src/rules/grammars/match.pest
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ field_path = ${ sep ~ ("\"" ~ segment_with_ws ~ "\"" | segment) ~ field_pat

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

// the order in which operators are evaluated is important
op = _{ eq | lte | lt | gte | gt | rex | flag }
eq = { "==" }
eq = { "==" | "is" }
lt = { "<" }
lte = { "<=" }
gt = { ">" }
Expand Down
36 changes: 34 additions & 2 deletions 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),
Some,
None,
}

Expand All @@ -71,6 +72,7 @@ impl MatchValue {
Self::Number(_) => "number",
Self::StringOrNumber(_, _) => "string_or_number",
Self::Regex(_) => "regex",
Self::Some => "some",
Self::None => "none",
}
}
Expand Down Expand Up @@ -226,13 +228,17 @@ impl FromStr for DirectMatch {

// 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" || str_value == "null";
let is_none = str_value == "none";
let is_some = str_value == "some";

let sanit_value = str_value.trim_matches('\'').trim_matches('"');

let (op, value) = match rule_op {
Rule::eq => (Op::Eq, {
if is_none {
MatchValue::None
} else if is_some {
MatchValue::Some
} 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 @@ -326,7 +332,8 @@ impl DirectMatch {
} else {
Err(())
},
),
)
.or(Ok(fv.is_some() && matches!(self.value, MatchValue::Some))),
Op::Gt => cmp_values!(Number, fv, >, self.value),
Op::Gte => cmp_values!(Number, fv, >=, self.value),
Op::Lt => cmp_values!(Number, fv, <, self.value),
Expand Down Expand Up @@ -391,6 +398,31 @@ mod test {
.unwrap()
.match_value(&"toast".into())
);

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

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

assert!(DirectMatch::from_str(r#".data is some"#)
.unwrap()
.match_value(&FieldValue::Number(42.into()))
.unwrap());

assert!(DirectMatch::from_str(r#".data is some"#)
.unwrap()
.match_value(&FieldValue::String("hello world".into()))
.unwrap());

assert!(!DirectMatch::from_str(r#".data is some"#)
.unwrap()
.match_value(&FieldValue::None)
.unwrap());
}

#[test]
Expand Down
17 changes: 15 additions & 2 deletions gene/src/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ pub enum FieldValue {
String(String),
Number(Number),
Bool(bool),
Some,
None,
}

Expand All @@ -212,6 +213,7 @@ impl std::fmt::Display for FieldValue {
Self::String(s) => write!(f, "{}", s),
Self::Number(s) => write!(f, "{}", s),
Self::Bool(b) => write!(f, "{}", b),
Self::Some => write!(f, "some"),
Self::None => write!(f, "none"),
}
}
Expand All @@ -223,6 +225,7 @@ impl FieldValue {
Self::Bool(_) => "bool",
Self::String(_) => "string",
Self::Number(_) => "number",
Self::Some => "some",
Self::None => "none",
}
}
Expand All @@ -232,13 +235,23 @@ impl FieldValue {
Self::Number(_) => Ok(self),
Self::String(s) => Ok(Self::Number(Number::from_str(&s)?)),
Self::Bool(b) => Ok(Self::Number((b as u8).into())),
Self::None => Err(NumberError::InvalidConvertion),
Self::None | Self::Some => Err(NumberError::InvalidConvertion),
}
}

pub(crate) fn is_string(&self) -> bool {
pub(crate) const fn is_string(&self) -> bool {
matches!(self, FieldValue::String(_))
}

#[inline(always)]
pub(crate) const fn is_some(&self) -> bool {
!self.is_none()
}

#[inline(always)]
pub(crate) const fn is_none(&self) -> bool {
matches!(self, FieldValue::None)
}
}

macro_rules! impl_field_value_number {
Expand Down

0 comments on commit f6bab0d

Please sign in to comment.