use crate::engine::error::Result;
use crate::engine::message::{Change, Message};
use datalogic_rs::{CompiledLogic, DataLogic};
use log::{debug, info};
use serde::Deserialize;
use serde_json::Value;
use std::sync::Arc;
pub const FILTER_STATUS_PASS: usize = 200;
pub const FILTER_STATUS_SKIP: usize = 298;
pub const FILTER_STATUS_HALT: usize = 299;
#[derive(Debug, Clone, Deserialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum RejectAction {
#[default]
Halt,
Skip,
}
#[derive(Debug, Clone, Deserialize)]
pub struct FilterConfig {
pub condition: Value,
#[serde(default)]
pub on_reject: RejectAction,
#[serde(skip)]
pub condition_index: Option<usize>,
}
impl FilterConfig {
pub fn execute(
&self,
message: &mut Message,
datalogic: &Arc<DataLogic>,
logic_cache: &[Arc<CompiledLogic>],
) -> Result<(usize, Vec<Change>)> {
let context_arc = message.get_context_arc();
let condition_met = match self.condition_index {
Some(idx) if idx < logic_cache.len() => {
match datalogic.evaluate(&logic_cache[idx], Arc::clone(&context_arc)) {
Ok(Value::Bool(true)) => true,
Ok(_) => false,
Err(e) => {
debug!("Filter: condition evaluation error: {:?}", e);
false
}
}
}
_ => {
debug!("Filter: condition not compiled, treating as not met");
false
}
};
if condition_met {
debug!("Filter: condition passed");
Ok((FILTER_STATUS_PASS, vec![]))
} else {
match self.on_reject {
RejectAction::Halt => {
info!("Filter: condition not met, halting workflow");
Ok((FILTER_STATUS_HALT, vec![]))
}
RejectAction::Skip => {
debug!("Filter: condition not met, skipping");
Ok((FILTER_STATUS_SKIP, vec![]))
}
}
}
}
}