dsq_core/ops/
logical_ops.rs1use crate::error::Result;
2use crate::Value;
3
4use super::Operation;
5
6pub struct AndOperation {
7 pub left_ops: Vec<Box<dyn Operation + Send + Sync>>,
8 pub right_ops: Vec<Box<dyn Operation + Send + Sync>>,
9}
10
11impl AndOperation {
12 #[must_use]
13 pub fn new(
14 left_ops: Vec<Box<dyn Operation + Send + Sync>>,
15 right_ops: Vec<Box<dyn Operation + Send + Sync>>,
16 ) -> Self {
17 Self {
18 left_ops,
19 right_ops,
20 }
21 }
22}
23
24impl Operation for AndOperation {
25 fn apply(&self, value: &Value) -> Result<Value> {
26 let mut left_val = value.clone();
27 for op in &self.left_ops {
28 left_val = op.apply(&left_val)?;
29 }
30
31 let left_truthy = match left_val {
32 Value::Bool(b) => b,
33 Value::Int(i) if i != 0 => true,
34 Value::Float(f) if f != 0.0 => true,
35 Value::String(s) if !s.is_empty() => true,
36 Value::Array(arr) if !arr.is_empty() => true,
37 Value::Object(obj) if !obj.is_empty() => true,
38 _ => false,
39 };
40
41 if !left_truthy {
42 return Ok(Value::Bool(false));
43 }
44
45 let mut right_val = value.clone();
46 for op in &self.right_ops {
47 right_val = op.apply(&right_val)?;
48 }
49
50 let right_truthy = match right_val {
51 Value::Bool(b) => b,
52 Value::Int(i) if i != 0 => true,
53 Value::Float(f) if f != 0.0 => true,
54 Value::String(s) if !s.is_empty() => true,
55 Value::Array(arr) if !arr.is_empty() => true,
56 Value::Object(obj) if !obj.is_empty() => true,
57 _ => false,
58 };
59
60 Ok(Value::Bool(right_truthy))
61 }
62
63 fn description(&self) -> String {
64 "logical and".to_string()
65 }
66}
67
68pub struct OrOperation {
69 pub left_ops: Vec<Box<dyn Operation + Send + Sync>>,
70 pub right_ops: Vec<Box<dyn Operation + Send + Sync>>,
71}
72
73impl OrOperation {
74 #[must_use]
75 pub fn new(
76 left_ops: Vec<Box<dyn Operation + Send + Sync>>,
77 right_ops: Vec<Box<dyn Operation + Send + Sync>>,
78 ) -> Self {
79 Self {
80 left_ops,
81 right_ops,
82 }
83 }
84}
85
86impl Operation for OrOperation {
87 fn apply(&self, value: &Value) -> Result<Value> {
88 let mut left_val = value.clone();
89 for op in &self.left_ops {
90 left_val = op.apply(&left_val)?;
91 }
92
93 let left_truthy = match left_val {
94 Value::Bool(b) => b,
95 Value::Int(i) if i != 0 => true,
96 Value::Float(f) if f != 0.0 => true,
97 Value::String(s) if !s.is_empty() => true,
98 Value::Array(arr) if !arr.is_empty() => true,
99 Value::Object(obj) if !obj.is_empty() => true,
100 _ => false,
101 };
102
103 if left_truthy {
104 return Ok(Value::Bool(true));
105 }
106
107 let mut right_val = value.clone();
108 for op in &self.right_ops {
109 right_val = op.apply(&right_val)?;
110 }
111
112 let right_truthy = match right_val {
113 Value::Bool(b) => b,
114 Value::Int(i) if i != 0 => true,
115 Value::Float(f) if f != 0.0 => true,
116 Value::String(s) if !s.is_empty() => true,
117 Value::Array(arr) if !arr.is_empty() => true,
118 Value::Object(obj) if !obj.is_empty() => true,
119 _ => false,
120 };
121
122 Ok(Value::Bool(right_truthy))
123 }
124
125 fn description(&self) -> String {
126 "logical or".to_string()
127 }
128}
129
130pub struct NegationOperation {
131 pub expr_ops: Vec<Box<dyn Operation + Send + Sync>>,
132}
133
134impl NegationOperation {
135 #[must_use]
136 pub fn new(expr_ops: Vec<Box<dyn Operation + Send + Sync>>) -> Self {
137 Self { expr_ops }
138 }
139}
140
141impl Operation for NegationOperation {
142 fn apply(&self, value: &Value) -> Result<Value> {
143 let mut expr_val = value.clone();
144 for op in &self.expr_ops {
145 expr_val = op.apply(&expr_val)?;
146 }
147
148 let truthy = match expr_val {
149 Value::Bool(b) => b,
150 Value::Int(i) if i != 0 => true,
151 Value::Float(f) if f != 0.0 => true,
152 Value::String(s) if !s.is_empty() => true,
153 Value::Array(arr) if !arr.is_empty() => true,
154 Value::Object(obj) if !obj.is_empty() => true,
155 _ => false,
156 };
157
158 Ok(Value::Bool(!truthy))
159 }
160
161 fn description(&self) -> String {
162 "logical not".to_string()
163 }
164}