datalogic_rs/builder/
comparison_builder.rs

1use crate::arena::DataArena;
2use crate::logic::ComparisonOp;
3use crate::logic::{Logic, OperatorType};
4
5/// Builder for comparison operations.
6///
7/// This builder provides a fluent interface for creating comparison operations
8/// such as equality, inequality, greater than, etc.
9pub struct ComparisonBuilder<'a> {
10    /// The arena in which all allocations will be made.
11    arena: &'a DataArena,
12}
13
14impl<'a> ComparisonBuilder<'a> {
15    /// Creates a new comparison builder.
16    pub fn new(arena: &'a DataArena) -> Self {
17        Self { arena }
18    }
19
20    /// Creates an equality comparison.
21    pub fn equal_op(&self) -> ComparisonOperationBuilder<'a> {
22        ComparisonOperationBuilder::new(self.arena, ComparisonOp::Equal)
23    }
24
25    /// Creates a strict equality comparison.
26    pub fn strict_equal_op(&self) -> ComparisonOperationBuilder<'a> {
27        ComparisonOperationBuilder::new(self.arena, ComparisonOp::StrictEqual)
28    }
29
30    /// Creates an inequality comparison.
31    pub fn not_equal_op(&self) -> ComparisonOperationBuilder<'a> {
32        ComparisonOperationBuilder::new(self.arena, ComparisonOp::NotEqual)
33    }
34
35    /// Creates a strict inequality comparison.
36    pub fn strict_not_equal_op(&self) -> ComparisonOperationBuilder<'a> {
37        ComparisonOperationBuilder::new(self.arena, ComparisonOp::StrictNotEqual)
38    }
39
40    /// Creates a greater than comparison.
41    pub fn greater_than_op(&self) -> ComparisonOperationBuilder<'a> {
42        ComparisonOperationBuilder::new(self.arena, ComparisonOp::GreaterThan)
43    }
44
45    /// Creates a greater than or equal comparison.
46    pub fn greater_than_or_equal_op(&self) -> ComparisonOperationBuilder<'a> {
47        ComparisonOperationBuilder::new(self.arena, ComparisonOp::GreaterThanOrEqual)
48    }
49
50    /// Creates a less than comparison.
51    pub fn less_than_op(&self) -> ComparisonOperationBuilder<'a> {
52        ComparisonOperationBuilder::new(self.arena, ComparisonOp::LessThan)
53    }
54
55    /// Creates a less than or equal comparison.
56    pub fn less_than_or_equal_op(&self) -> ComparisonOperationBuilder<'a> {
57        ComparisonOperationBuilder::new(self.arena, ComparisonOp::LessThanOrEqual)
58    }
59}
60
61/// Builder for a comparison operation with its operands.
62pub struct ComparisonOperationBuilder<'a> {
63    /// The arena in which all allocations will be made.
64    arena: &'a DataArena,
65    /// The comparison operator to use.
66    operation: ComparisonOp,
67    /// The operands of the comparison.
68    operands: Vec<Logic<'a>>,
69}
70
71impl<'a> ComparisonOperationBuilder<'a> {
72    /// Creates a new comparison operation builder.
73    pub fn new(arena: &'a DataArena, operation: ComparisonOp) -> Self {
74        Self {
75            arena,
76            operation,
77            operands: Vec::new(),
78        }
79    }
80
81    /// Adds an operand to the comparison.
82    pub fn operand(mut self, value: Logic<'a>) -> Self {
83        self.operands.push(value);
84        self
85    }
86
87    /// Adds a variable operand to the comparison.
88    pub fn var(self, path: &str) -> Self {
89        let var = Logic::variable(path, None, self.arena);
90        self.operand(var)
91    }
92
93    /// Adds a literal value operand to the comparison.
94    pub fn value<T: Into<crate::value::DataValue<'a>>>(mut self, value: T) -> Self {
95        let val = Logic::literal(value.into(), self.arena);
96        self.operands.push(val);
97        self
98    }
99
100    /// Adds an integer value operand to the comparison.
101    pub fn int(mut self, value: i64) -> Self {
102        let val = Logic::literal(crate::value::DataValue::integer(value), self.arena);
103        self.operands.push(val);
104        self
105    }
106
107    /// Adds a float value operand to the comparison.
108    pub fn float(mut self, value: f64) -> Self {
109        let val = Logic::literal(crate::value::DataValue::float(value), self.arena);
110        self.operands.push(val);
111        self
112    }
113
114    /// Adds a string value operand to the comparison.
115    pub fn string(mut self, value: &str) -> Self {
116        let val = Logic::literal(
117            crate::value::DataValue::string(self.arena, value),
118            self.arena,
119        );
120        self.operands.push(val);
121        self
122    }
123
124    /// Adds a boolean value operand to the comparison.
125    pub fn bool(mut self, value: bool) -> Self {
126        let val = Logic::literal(crate::value::DataValue::bool(value), self.arena);
127        self.operands.push(val);
128        self
129    }
130
131    /// Builds the comparison operation with the current operands.
132    ///
133    /// If no operands are set, it will use null as the default.
134    /// If only one operand is set, it will create an "is truthy" check by comparing with true.
135    pub fn build(self) -> Logic<'a> {
136        let mut final_operands = self.operands;
137
138        // If no operands are set, use null as the default
139        if final_operands.is_empty() {
140            final_operands.push(Logic::literal(crate::value::DataValue::null(), self.arena));
141        }
142
143        // If only one operand is set, add true as second operand for a "is truthy" check
144        if final_operands.len() == 1 {
145            final_operands.push(Logic::literal(
146                crate::value::DataValue::bool(true),
147                self.arena,
148            ));
149        }
150
151        Logic::operator(
152            OperatorType::Comparison(self.operation),
153            final_operands,
154            self.arena,
155        )
156    }
157}