postgrest_parser/ast/
logic.rs1use 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}