use std::sync::Arc;
use crate::types::{Node, PropertyValue};
pub type NodePredicate = Arc<dyn Fn(&Node) -> bool + Send + Sync>;
pub struct FilterBuilder;
impl FilterBuilder {
pub fn label(label: impl Into<String>) -> NodePredicate {
let label = label.into();
Arc::new(move |node: &Node| node.label == label)
}
pub fn has_property(key: impl Into<String>) -> NodePredicate {
let key = key.into();
Arc::new(move |node: &Node| node.properties.contains_key(&key))
}
pub fn property_eq(key: impl Into<String>, value: impl Into<String>) -> NodePredicate {
let key = key.into();
let value = PropertyValue::String(value.into());
Arc::new(move |node: &Node| {
node.properties.get(&key) == Some(&value)
})
}
pub fn property_gt(key: impl Into<String>, threshold: i64) -> NodePredicate {
let key = key.into();
Arc::new(move |node: &Node| {
if let Some(PropertyValue::Int(val)) = node.properties.get(&key) {
*val > threshold
} else {
false
}
})
}
pub fn and(p1: NodePredicate, p2: NodePredicate) -> NodePredicate {
Arc::new(move |node: &Node| p1(node) && p2(node))
}
pub fn or(p1: NodePredicate, p2: NodePredicate) -> NodePredicate {
Arc::new(move |node: &Node| p1(node) || p2(node))
}
pub fn not(p: NodePredicate) -> NodePredicate {
Arc::new(move |node: &Node| !p(node))
}
}