Skip to main content

postgrest_parser/ast/
logic.rs

1use super::Filter;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
5#[serde(rename_all = "snake_case")]
6pub enum LogicOperator {
7    And,
8    Or,
9}
10
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12pub enum LogicCondition {
13    Filter(Filter),
14    Logic(LogicTree),
15}
16
17impl From<Filter> for LogicCondition {
18    fn from(filter: Filter) -> Self {
19        LogicCondition::Filter(filter)
20    }
21}
22
23impl From<LogicTree> for LogicCondition {
24    fn from(tree: LogicTree) -> Self {
25        LogicCondition::Logic(tree)
26    }
27}
28
29#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
30pub struct LogicTree {
31    pub operator: LogicOperator,
32    pub conditions: Vec<LogicCondition>,
33    pub negated: bool,
34}
35
36impl LogicTree {
37    pub fn new(operator: LogicOperator) -> Self {
38        Self {
39            operator,
40            conditions: Vec::new(),
41            negated: false,
42        }
43    }
44
45    pub fn with_conditions(mut self, conditions: Vec<LogicCondition>) -> Self {
46        self.conditions = conditions;
47        self
48    }
49
50    pub fn and() -> Self {
51        Self::new(LogicOperator::And)
52    }
53
54    pub fn or() -> Self {
55        Self::new(LogicOperator::Or)
56    }
57
58    pub fn negated(mut self) -> Self {
59        self.negated = true;
60        self
61    }
62
63    pub fn add_condition(mut self, condition: LogicCondition) -> Self {
64        self.conditions.push(condition);
65        self
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72    use crate::ast::{Field, FilterOperator, FilterValue};
73
74    #[test]
75    fn test_logic_tree_and() {
76        let tree = LogicTree::and();
77        assert_eq!(tree.operator, LogicOperator::And);
78        assert!(!tree.negated);
79        assert!(tree.conditions.is_empty());
80    }
81
82    #[test]
83    fn test_logic_tree_or() {
84        let tree = LogicTree::or();
85        assert_eq!(tree.operator, LogicOperator::Or);
86    }
87
88    #[test]
89    fn test_logic_tree_with_conditions() {
90        let filter1 = Filter::new(
91            Field::new("id"),
92            FilterOperator::Eq,
93            FilterValue::Single("1".to_string()),
94        );
95        let filter2 = Filter::new(
96            Field::new("status"),
97            FilterOperator::Eq,
98            FilterValue::Single("active".to_string()),
99        );
100
101        let tree = LogicTree::and().with_conditions(vec![filter1.into(), filter2.into()]);
102
103        assert_eq!(tree.conditions.len(), 2);
104    }
105
106    #[test]
107    fn test_logic_tree_negated() {
108        let tree = LogicTree::and().negated();
109        assert!(tree.negated);
110    }
111
112    #[test]
113    fn test_logic_condition_from_filter() {
114        let filter = Filter::new(
115            Field::new("id"),
116            FilterOperator::Eq,
117            FilterValue::Single("1".to_string()),
118        );
119        let condition = LogicCondition::from(filter);
120        assert!(matches!(condition, LogicCondition::Filter(_)));
121    }
122
123    #[test]
124    fn test_logic_condition_from_tree() {
125        let tree = LogicTree::or();
126        let condition = LogicCondition::from(tree);
127        assert!(matches!(condition, LogicCondition::Logic(_)));
128    }
129
130    #[test]
131    fn test_logic_tree_serialization() {
132        let tree = LogicTree::and().negated();
133        let json = serde_json::to_string(&tree).unwrap();
134        assert!(json.contains("and"));
135        assert!(json.contains("negated"));
136    }
137}