1use core::fmt;
5use std::fmt::{Display, Formatter};
6
7use vortex_array::compute;
8use vortex_error::{VortexError, VortexResult, vortex_bail};
9use vortex_proto::expr::binary_opts::BinaryOp;
10
11#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub enum Operator {
19 Eq,
21 NotEq,
23 Gt,
25 Gte,
27 Lt,
29 Lte,
31 And,
33 Or,
35 Add,
39 Sub,
45}
46
47impl From<Operator> for i32 {
48 fn from(value: Operator) -> Self {
49 let op: BinaryOp = value.into();
50 op.into()
51 }
52}
53
54impl From<Operator> for BinaryOp {
55 fn from(value: Operator) -> Self {
56 match value {
57 Operator::Eq => BinaryOp::Eq,
58 Operator::NotEq => BinaryOp::NotEq,
59 Operator::Gt => BinaryOp::Gt,
60 Operator::Gte => BinaryOp::Gte,
61 Operator::Lt => BinaryOp::Lt,
62 Operator::Lte => BinaryOp::Lte,
63 Operator::And => BinaryOp::And,
64 Operator::Or => BinaryOp::Or,
65 Operator::Add => BinaryOp::Add,
66 Operator::Sub => BinaryOp::Sub,
67 }
68 }
69}
70
71impl TryFrom<i32> for Operator {
72 type Error = VortexError;
73
74 fn try_from(value: i32) -> Result<Self, Self::Error> {
75 Ok(BinaryOp::try_from(value)?.into())
76 }
77}
78
79impl From<BinaryOp> for Operator {
80 fn from(value: BinaryOp) -> Self {
81 match value {
82 BinaryOp::Eq => Operator::Eq,
83 BinaryOp::NotEq => Operator::NotEq,
84 BinaryOp::Gt => Operator::Gt,
85 BinaryOp::Gte => Operator::Gte,
86 BinaryOp::Lt => Operator::Lt,
87 BinaryOp::Lte => Operator::Lte,
88 BinaryOp::And => Operator::And,
89 BinaryOp::Or => Operator::Or,
90 BinaryOp::Add => Operator::Add,
91 BinaryOp::Sub => Operator::Sub,
92 }
93 }
94}
95
96impl Display for Operator {
97 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
98 let display = match &self {
99 Operator::Eq => "=",
100 Operator::NotEq => "!=",
101 Operator::Gt => ">",
102 Operator::Gte => ">=",
103 Operator::Lt => "<",
104 Operator::Lte => "<=",
105 Operator::And => "and",
106 Operator::Or => "or",
107 Operator::Add => "+",
108 Operator::Sub => "-",
109 };
110 Display::fmt(display, f)
111 }
112}
113
114impl Operator {
115 pub fn inverse(self) -> Option<Self> {
116 match self {
117 Operator::Eq => Some(Operator::NotEq),
118 Operator::NotEq => Some(Operator::Eq),
119 Operator::Gt => Some(Operator::Lte),
120 Operator::Gte => Some(Operator::Lt),
121 Operator::Lt => Some(Operator::Gte),
122 Operator::Lte => Some(Operator::Gt),
123 Operator::And | Operator::Or | Operator::Add | Operator::Sub => None,
124 }
125 }
126
127 pub fn logical_inverse(self) -> Option<Self> {
128 match self {
129 Operator::And => Some(Operator::Or),
130 Operator::Or => Some(Operator::And),
131 _ => None,
132 }
133 }
134
135 pub fn swap(self) -> Self {
137 match self {
138 Operator::Eq => Operator::Eq,
139 Operator::NotEq => Operator::NotEq,
140 Operator::Gt => Operator::Lt,
141 Operator::Gte => Operator::Lte,
142 Operator::Lt => Operator::Gt,
143 Operator::Lte => Operator::Gte,
144 Operator::And => Operator::And,
145 Operator::Or => Operator::Or,
146 Operator::Add => Operator::Add,
147 Operator::Sub => Operator::Sub,
148 }
149 }
150
151 pub fn maybe_cmp_operator(self) -> Option<compute::Operator> {
152 match self {
153 Operator::Eq => Some(compute::Operator::Eq),
154 Operator::NotEq => Some(compute::Operator::NotEq),
155 Operator::Lt => Some(compute::Operator::Lt),
156 Operator::Lte => Some(compute::Operator::Lte),
157 Operator::Gt => Some(compute::Operator::Gt),
158 Operator::Gte => Some(compute::Operator::Gte),
159 _ => None,
160 }
161 }
162}
163
164impl From<compute::Operator> for Operator {
165 fn from(cmp_operator: compute::Operator) -> Self {
166 match cmp_operator {
167 compute::Operator::Eq => Operator::Eq,
168 compute::Operator::NotEq => Operator::NotEq,
169 compute::Operator::Gt => Operator::Gt,
170 compute::Operator::Gte => Operator::Gte,
171 compute::Operator::Lt => Operator::Lt,
172 compute::Operator::Lte => Operator::Lte,
173 }
174 }
175}
176
177impl TryInto<compute::Operator> for Operator {
178 type Error = VortexError;
179
180 fn try_into(self) -> VortexResult<compute::Operator> {
181 Ok(match self {
182 Operator::Eq => compute::Operator::Eq,
183 Operator::NotEq => compute::Operator::NotEq,
184 Operator::Gt => compute::Operator::Gt,
185 Operator::Gte => compute::Operator::Gte,
186 Operator::Lt => compute::Operator::Lt,
187 Operator::Lte => compute::Operator::Lte,
188 _ => vortex_bail!("Not a compute operator: {}", self),
189 })
190 }
191}