1use core::fmt;
2use std::fmt::{Display, Formatter};
3
4use vortex_array::compute;
5
6#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub enum Operator {
9 Eq,
11 NotEq,
12 Gt,
13 Gte,
14 Lt,
15 Lte,
16 And,
18 Or,
19}
20
21#[cfg(feature = "proto")]
22mod proto {
23 use vortex_error::VortexError;
24 use vortex_proto::expr::kind::BinaryOp;
25
26 use crate::Operator;
27
28 impl From<Operator> for i32 {
29 fn from(value: Operator) -> Self {
30 let op: BinaryOp = value.into();
31 op.into()
32 }
33 }
34
35 impl From<Operator> for BinaryOp {
36 fn from(value: Operator) -> Self {
37 match value {
38 Operator::Eq => BinaryOp::Eq,
39 Operator::NotEq => BinaryOp::NotEq,
40 Operator::Gt => BinaryOp::Gt,
41 Operator::Gte => BinaryOp::Gte,
42 Operator::Lt => BinaryOp::Lt,
43 Operator::Lte => BinaryOp::Lte,
44 Operator::And => BinaryOp::And,
45 Operator::Or => BinaryOp::Or,
46 }
47 }
48 }
49
50 impl TryFrom<i32> for Operator {
51 type Error = VortexError;
52
53 fn try_from(value: i32) -> Result<Self, Self::Error> {
54 Ok(BinaryOp::try_from(value)?.into())
55 }
56 }
57
58 impl From<BinaryOp> for Operator {
59 fn from(value: BinaryOp) -> Self {
60 match value {
61 BinaryOp::Eq => Operator::Eq,
62 BinaryOp::NotEq => Operator::NotEq,
63 BinaryOp::Gt => Operator::Gt,
64 BinaryOp::Gte => Operator::Gte,
65 BinaryOp::Lt => Operator::Lt,
66 BinaryOp::Lte => Operator::Lte,
67 BinaryOp::And => Operator::And,
68 BinaryOp::Or => Operator::Or,
69 }
70 }
71 }
72}
73
74impl Display for Operator {
75 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
76 let display = match &self {
77 Operator::Eq => "=",
78 Operator::NotEq => "!=",
79 Operator::Gt => ">",
80 Operator::Gte => ">=",
81 Operator::Lt => "<",
82 Operator::Lte => "<=",
83 Operator::And => "and",
84 Operator::Or => "or",
85 };
86 Display::fmt(display, f)
87 }
88}
89
90impl Operator {
91 pub fn inverse(self) -> Option<Self> {
92 match self {
93 Operator::Eq => Some(Operator::NotEq),
94 Operator::NotEq => Some(Operator::Eq),
95 Operator::Gt => Some(Operator::Lte),
96 Operator::Gte => Some(Operator::Lt),
97 Operator::Lt => Some(Operator::Gte),
98 Operator::Lte => Some(Operator::Gt),
99 Operator::And | Operator::Or => None,
100 }
101 }
102
103 pub fn logical_inverse(self) -> Option<Self> {
104 match self {
105 Operator::And => Some(Operator::Or),
106 Operator::Or => Some(Operator::And),
107 _ => None,
108 }
109 }
110
111 pub fn swap(self) -> Self {
113 match self {
114 Operator::Eq => Operator::Eq,
115 Operator::NotEq => Operator::NotEq,
116 Operator::Gt => Operator::Lt,
117 Operator::Gte => Operator::Lte,
118 Operator::Lt => Operator::Gt,
119 Operator::Lte => Operator::Gte,
120 Operator::And => Operator::And,
121 Operator::Or => Operator::Or,
122 }
123 }
124
125 pub fn maybe_cmp_operator(self) -> Option<compute::Operator> {
126 match self {
127 Operator::Eq => Some(compute::Operator::Eq),
128 Operator::NotEq => Some(compute::Operator::NotEq),
129 Operator::Lt => Some(compute::Operator::Lt),
130 Operator::Lte => Some(compute::Operator::Lte),
131 Operator::Gt => Some(compute::Operator::Gt),
132 Operator::Gte => Some(compute::Operator::Gte),
133 _ => None,
134 }
135 }
136}
137
138impl From<compute::Operator> for Operator {
139 fn from(cmp_operator: compute::Operator) -> Self {
140 match cmp_operator {
141 compute::Operator::Eq => Operator::Eq,
142 compute::Operator::NotEq => Operator::NotEq,
143 compute::Operator::Gt => Operator::Gt,
144 compute::Operator::Gte => Operator::Gte,
145 compute::Operator::Lt => Operator::Lt,
146 compute::Operator::Lte => Operator::Lte,
147 }
148 }
149}