1use crate::mappers::CachedMapper;
22use crate::utils::ExpressionRawPointer;
23use crate::{BinaryOpType, Expression, LiteralT, SmallVecExprT, UnaryOpType};
24use std::rc::Rc;
25
26pub trait IdentityMapper: CachedMapper<ExpressionRawPointer, Rc<Expression>> {
29 fn visit(&mut self, expr: Rc<Expression>) -> Rc<Expression> {
30 let cache_key = ExpressionRawPointer(expr.clone());
31 match self.query_cache(&cache_key) {
32 Some(x) => x.clone(),
33 None => {
34 let result = match &*expr {
35 Expression::Scalar(s) => self.map_scalar(&s),
36 Expression::Variable(name) => self.map_variable(name.to_string()),
37 Expression::UnaryOp(op, x) => self.map_unary_op(op.clone(), &x),
38 Expression::BinaryOp(l, op, r) => self.map_binary_op(&l, op.clone(), &r),
39 Expression::Call(call, params) => self.map_call(&call, ¶ms),
40 Expression::Subscript(agg, indices) => self.map_subscript(&agg, &indices),
41 Expression::If(cond, then, else_) => self.map_if(&cond, &then, &else_),
42 };
43 self.add_to_cache(cache_key, result.clone());
44 result
45 }
46 }
47 }
48
49 fn map_scalar(&mut self, value: &LiteralT) -> Rc<Expression> {
50 Rc::new(Expression::Scalar(value.clone()))
51 }
52
53 fn map_variable(&mut self, name: String) -> Rc<Expression> {
54 Rc::new(Expression::Variable(name))
55 }
56
57 fn map_unary_op(&mut self, op: UnaryOpType, x: &Rc<Expression>) -> Rc<Expression> {
58 Rc::new(Expression::UnaryOp(op, self.visit(x.clone())))
59 }
60
61 fn map_binary_op(&mut self, left: &Rc<Expression>, op: BinaryOpType, right: &Rc<Expression>)
62 -> Rc<Expression> {
63 Rc::new(Expression::BinaryOp(self.visit(left.clone()), op, self.visit(right.clone())))
64 }
65
66 fn map_call(&mut self, call: &Rc<Expression>, params: &SmallVecExprT) -> Rc<Expression> {
67 Rc::new(Expression::Call(self.visit(call.clone()),
68 params.iter()
69 .map(|param| self.visit(param.clone()))
70 .collect()))
71 }
72
73 fn map_subscript(&mut self, agg: &Rc<Expression>, indices: &SmallVecExprT) -> Rc<Expression> {
74 Rc::new(Expression::Subscript(self.visit(agg.clone()),
75 indices.iter().map(|idx| self.visit(idx.clone())).collect()))
76 }
77
78 fn map_if(&mut self, cond: &Rc<Expression>, then: &Rc<Expression>, else_: &Rc<Expression>)
79 -> Rc<Expression> {
80 Rc::new(Expression::If(self.visit(cond.clone()),
81 self.visit(then.clone()),
82 self.visit(else_.clone())))
83 }
84}
85
86pub trait UncachedIdentityMapper {
91 fn visit(&self, expr: &Expression) -> Rc<Expression> {
92 match expr {
93 Expression::Scalar(s) => self.map_scalar(&s),
94 Expression::Variable(name) => self.map_variable(name.to_string()),
95 Expression::UnaryOp(op, x) => self.map_unary_op(op.clone(), &x),
96 Expression::BinaryOp(l, op, r) => self.map_binary_op(&l, op.clone(), &r),
97 Expression::Call(call, params) => self.map_call(&call, ¶ms),
98 Expression::Subscript(agg, indices) => self.map_subscript(&agg, &indices),
99 Expression::If(cond, then, else_) => self.map_if(&cond, &then, &else_),
100 }
101 }
102
103 fn map_scalar(&self, value: &LiteralT) -> Rc<Expression> {
104 Rc::new(Expression::Scalar(value.clone()))
105 }
106
107 fn map_variable(&self, name: String) -> Rc<Expression> {
108 Rc::new(Expression::Variable(name))
109 }
110
111 fn map_unary_op(&self, op: UnaryOpType, x: &Rc<Expression>) -> Rc<Expression> {
112 Rc::new(Expression::UnaryOp(op, self.visit(x)))
113 }
114
115 fn map_binary_op(&self, left: &Rc<Expression>, op: BinaryOpType, right: &Rc<Expression>)
116 -> Rc<Expression> {
117 Rc::new(Expression::BinaryOp(self.visit(left), op, self.visit(right)))
118 }
119
120 fn map_call(&self, call: &Rc<Expression>, params: &SmallVecExprT) -> Rc<Expression> {
121 Rc::new(Expression::Call(self.visit(call),
122 params.iter().map(|param| self.visit(param)).collect()))
123 }
124
125 fn map_subscript(&self, agg: &Rc<Expression>, indices: &SmallVecExprT) -> Rc<Expression> {
126 Rc::new(Expression::Subscript(self.visit(agg),
127 indices.iter().map(|idx| self.visit(idx)).collect()))
128 }
129
130 fn map_if(&self, cond: &Rc<Expression>, then: &Rc<Expression>, else_: &Rc<Expression>)
131 -> Rc<Expression> {
132 Rc::new(Expression::If(self.visit(cond), self.visit(then), self.visit(else_)))
133 }
134}
135
136pub trait IdentityMapperWithContext {
141 type Context;
142
143 fn visit(&self, expr: &Expression, context: &Self::Context) -> Rc<Expression> {
144 match expr {
145 Expression::Scalar(s) => self.map_scalar(&s, context),
146 Expression::Variable(name) => self.map_variable(name.to_string(), context),
147 Expression::UnaryOp(op, x) => self.map_unary_op(op.clone(), &x, context),
148 Expression::BinaryOp(l, op, r) => self.map_binary_op(&l, op.clone(), &r, context),
149 Expression::Call(call, params) => self.map_call(&call, ¶ms, context),
150 Expression::Subscript(agg, indices) => self.map_subscript(&agg, &indices, context),
151 Expression::If(cond, then, else_) => self.map_if(&cond, &then, &else_, context),
152 }
153 }
154
155 fn map_scalar(&self, value: &LiteralT, _context: &Self::Context) -> Rc<Expression> {
156 Rc::new(Expression::Scalar(value.clone()))
157 }
158
159 fn map_variable(&self, name: String, _context: &Self::Context) -> Rc<Expression> {
160 Rc::new(Expression::Variable(name))
161 }
162
163 fn map_unary_op(&self, op: UnaryOpType, x: &Rc<Expression>, context: &Self::Context)
164 -> Rc<Expression> {
165 Rc::new(Expression::UnaryOp(op, self.visit(x, context)))
166 }
167
168 fn map_binary_op(&self, left: &Rc<Expression>, op: BinaryOpType, right: &Rc<Expression>,
169 context: &Self::Context)
170 -> Rc<Expression> {
171 Rc::new(Expression::BinaryOp(self.visit(left, context), op, self.visit(right, context)))
172 }
173
174 fn map_call(&self, call: &Rc<Expression>, params: &SmallVecExprT, context: &Self::Context)
175 -> Rc<Expression> {
176 Rc::new(Expression::Call(self.visit(call, context),
177 params.iter()
178 .map(|param| self.visit(param, context))
179 .collect()))
180 }
181
182 fn map_subscript(&self, agg: &Rc<Expression>, indices: &SmallVecExprT,
183 context: &Self::Context)
184 -> Rc<Expression> {
185 Rc::new(Expression::Subscript(self.visit(agg, context),
186 indices.iter().map(|idx| self.visit(idx, context)).collect()))
187 }
188
189 fn map_if(&self, cond: &Rc<Expression>, then: &Rc<Expression>, else_: &Rc<Expression>,
190 context: &Self::Context)
191 -> Rc<Expression> {
192 Rc::new(Expression::If(self.visit(cond, context),
193 self.visit(then, context),
194 self.visit(else_, context)))
195 }
196}
197
198pub trait IdentityMapperWithCustomCacheKey: CachedMapper<Self::CacheKey, Rc<Expression>> {
203 type CacheKey;
204
205 fn get_cache_key(&self, expr: Rc<Expression>) -> Self::CacheKey;
206
207 fn visit(&mut self, expr: Rc<Expression>) -> Rc<Expression> {
208 let cache_key = self.get_cache_key(expr.clone());
209 match self.query_cache(&cache_key) {
210 Some(x) => x.clone(),
211 None => {
212 let result = match &*expr {
213 Expression::Scalar(s) => self.map_scalar(&s),
214 Expression::Variable(name) => self.map_variable(name.to_string()),
215 Expression::UnaryOp(op, x) => self.map_unary_op(op.clone(), &x),
216 Expression::BinaryOp(l, op, r) => self.map_binary_op(&l, op.clone(), &r),
217 Expression::Call(call, params) => self.map_call(&call, ¶ms),
218 Expression::Subscript(agg, indices) => self.map_subscript(&agg, &indices),
219 Expression::If(cond, then, else_) => self.map_if(&cond, &then, &else_),
220 };
221 self.add_to_cache(cache_key, result.clone());
222 result
223 }
224 }
225 }
226
227 fn map_scalar(&mut self, value: &LiteralT) -> Rc<Expression> {
228 Rc::new(Expression::Scalar(value.clone()))
229 }
230
231 fn map_variable(&mut self, name: String) -> Rc<Expression> {
232 Rc::new(Expression::Variable(name))
233 }
234
235 fn map_unary_op(&mut self, op: UnaryOpType, x: &Rc<Expression>) -> Rc<Expression> {
236 Rc::new(Expression::UnaryOp(op, self.visit(x.clone())))
237 }
238
239 fn map_binary_op(&mut self, left: &Rc<Expression>, op: BinaryOpType, right: &Rc<Expression>)
240 -> Rc<Expression> {
241 Rc::new(Expression::BinaryOp(self.visit(left.clone()), op, self.visit(right.clone())))
242 }
243
244 fn map_call(&mut self, call: &Rc<Expression>, params: &SmallVecExprT) -> Rc<Expression> {
245 Rc::new(Expression::Call(self.visit(call.clone()),
246 params.iter()
247 .map(|param| self.visit(param.clone()))
248 .collect()))
249 }
250
251 fn map_subscript(&mut self, agg: &Rc<Expression>, indices: &SmallVecExprT) -> Rc<Expression> {
252 Rc::new(Expression::Subscript(self.visit(agg.clone()),
253 indices.iter().map(|idx| self.visit(idx.clone())).collect()))
254 }
255
256 fn map_if(&mut self, cond: &Rc<Expression>, then: &Rc<Expression>, else_: &Rc<Expression>)
257 -> Rc<Expression> {
258 Rc::new(Expression::If(self.visit(cond.clone()),
259 self.visit(then.clone()),
260 self.visit(else_.clone())))
261 }
262}
263
264