vortex_expr/
operators.rs

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    // comparison
10    Eq,
11    NotEq,
12    Gt,
13    Gte,
14    Lt,
15    Lte,
16    // boolean algebra
17    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    /// Change the sides of the operator, where changing lhs and rhs won't change the result of the operation
112    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}