#![recursion_limit = "2048"]
pub mod error;
pub mod evaluator;
pub mod expression;
pub mod index;
pub use error::{FilterError, Result};
pub use evaluator::FilterEvaluator;
pub use expression::FilterExpression;
pub use index::{IndexType, PayloadIndex, PayloadIndexManager};
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn test_full_workflow() {
let mut manager = PayloadIndexManager::new();
manager.create_index("status", IndexType::Keyword).unwrap();
manager.create_index("age", IndexType::Integer).unwrap();
manager.create_index("score", IndexType::Float).unwrap();
manager
.index_payload(
"v1",
&json!({
"status": "active",
"age": 25,
"score": 0.9
}),
)
.unwrap();
manager
.index_payload(
"v2",
&json!({
"status": "active",
"age": 30,
"score": 0.85
}),
)
.unwrap();
manager
.index_payload(
"v3",
&json!({
"status": "inactive",
"age": 25,
"score": 0.7
}),
)
.unwrap();
let filter = FilterExpression::and(vec![
FilterExpression::eq("status", json!("active")),
FilterExpression::or(vec![
FilterExpression::gte("age", json!(30)),
FilterExpression::gte("score", json!(0.9)),
]),
]);
let evaluator = FilterEvaluator::new(&manager);
let results = evaluator.evaluate(&filter).unwrap();
assert_eq!(results.len(), 2);
assert!(results.contains("v1"));
assert!(results.contains("v2"));
}
#[test]
fn test_text_matching() {
let mut manager = PayloadIndexManager::new();
manager
.create_index("description", IndexType::Text)
.unwrap();
manager
.index_payload(
"v1",
&json!({
"description": "The quick brown fox"
}),
)
.unwrap();
manager
.index_payload(
"v2",
&json!({
"description": "The lazy dog"
}),
)
.unwrap();
let evaluator = FilterEvaluator::new(&manager);
let filter = FilterExpression::match_text("description", "quick");
let results = evaluator.evaluate(&filter).unwrap();
assert_eq!(results.len(), 1);
assert!(results.contains("v1"));
}
#[test]
fn test_not_filter() {
let mut manager = PayloadIndexManager::new();
manager.create_index("status", IndexType::Keyword).unwrap();
manager
.index_payload("v1", &json!({"status": "active"}))
.unwrap();
manager
.index_payload("v2", &json!({"status": "inactive"}))
.unwrap();
let evaluator = FilterEvaluator::new(&manager);
let filter = FilterExpression::not(FilterExpression::eq("status", json!("active")));
let results = evaluator.evaluate(&filter).unwrap();
assert_eq!(results.len(), 1);
assert!(results.contains("v2"));
}
#[test]
fn test_in_filter() {
let mut manager = PayloadIndexManager::new();
manager.create_index("status", IndexType::Keyword).unwrap();
manager
.index_payload("v1", &json!({"status": "active"}))
.unwrap();
manager
.index_payload("v2", &json!({"status": "pending"}))
.unwrap();
manager
.index_payload("v3", &json!({"status": "inactive"}))
.unwrap();
let evaluator = FilterEvaluator::new(&manager);
let filter = FilterExpression::in_values("status", vec![json!("active"), json!("pending")]);
let results = evaluator.evaluate(&filter).unwrap();
assert_eq!(results.len(), 2);
assert!(results.contains("v1"));
assert!(results.contains("v2"));
}
}