///|
fn find_condition_capture(captures : Array[Capture], name : String) -> Capture? {
for capture in captures {
if capture.name == name {
return Some(capture)
}
}
None
}
///|
fn compare_condition_fields(
left : Value?,
comparison : Comparison,
right : Value?,
) -> Bool {
match (left, right) {
(Some(a), Some(b)) => a.compare(comparison, b)
_ => false
}
}
///|
/// Evaluates an already validated condition. Missing fields and incompatible
/// types compare false, including NotEqual; Not then uses ordinary Boolean
/// negation. Empty All is true and empty Any is false. A capture field uses its
/// last event; an existing empty optional capture has count zero.
fn Condition::evaluate_unchecked(
self : Condition,
event : Event,
captures : Array[Capture],
) -> Bool {
match self {
Always => true
Kind(kind) => event.kind() == kind
Has(field) => event.field(field) is Some(_)
Compare(field, comparison, value) =>
compare_condition_fields(event.field(field), comparison, Some(value))
FieldCompare(left, comparison, right) =>
compare_condition_fields(
event.field(left),
comparison,
event.field(right),
)
CaptureCompare(field, comparison, stage, captured_field) => {
guard find_condition_capture(captures, stage) is Some(capture) else {
return false
}
guard !capture.events.is_empty() else { return false }
let last = capture.events[capture.events.length() - 1]
compare_condition_fields(
event.field(field),
comparison,
last.field(captured_field),
)
}
CaptureCount(stage, comparison, count) =>
match find_condition_capture(captures, stage) {
Some(capture) =>
compare_order(capture.events.length().compare(count), comparison)
None => false
}
TextPrefix(field, prefix) =>
match event.field(field) {
Some(Text(text)) => text.has_prefix(prefix)
_ => false
}
TextContains(field, part) =>
match event.field(field) {
Some(Text(text)) => text.contains(part)
_ => false
}
All(children) => {
for child in children {
if !child.evaluate_unchecked(event, captures) {
return false
}
}
true
}
Any(children) => {
for child in children {
if child.evaluate_unchecked(event, captures) {
return true
}
}
false
}
Not(child) => !child.evaluate_unchecked(event, captures)
}
}