1use clicktype_core::traits::Numeric;
4use crate::expr::Expression;
5
6pub mod date {
9 use super::*;
10
11 pub struct ToDateExpr<E: Expression>(pub E);
13
14 impl<E: Expression> Expression for ToDateExpr<E> {
15 type Output = chrono::NaiveDate;
16
17 fn render(&self) -> String {
18 format!("toDate({})", self.0.render())
19 }
20 }
21
22 pub fn to_date<E: Expression>(expr: E) -> ToDateExpr<E> {
23 ToDateExpr(expr)
24 }
25
26 pub struct ToDateTimeExpr<E: Expression>(pub E);
28
29 impl<E: Expression> Expression for ToDateTimeExpr<E> {
30 type Output = chrono::NaiveDateTime;
31
32 fn render(&self) -> String {
33 format!("toDateTime({})", self.0.render())
34 }
35 }
36
37 pub fn to_datetime<E: Expression>(expr: E) -> ToDateTimeExpr<E> {
38 ToDateTimeExpr(expr)
39 }
40
41 pub struct ToYYYYMMExpr<E: Expression>(pub E);
43
44 impl<E: Expression> Expression for ToYYYYMMExpr<E> {
45 type Output = u32;
46
47 fn render(&self) -> String {
48 format!("toYYYYMM({})", self.0.render())
49 }
50 }
51
52 pub fn to_yyyymm<E: Expression>(expr: E) -> ToYYYYMMExpr<E> {
53 ToYYYYMMExpr(expr)
54 }
55
56 pub struct ToStartOfDayExpr<E: Expression>(pub E);
58
59 impl<E: Expression> Expression for ToStartOfDayExpr<E> {
60 type Output = chrono::NaiveDateTime;
61
62 fn render(&self) -> String {
63 format!("toStartOfDay({})", self.0.render())
64 }
65 }
66
67 pub fn to_start_of_day<E: Expression>(expr: E) -> ToStartOfDayExpr<E> {
68 ToStartOfDayExpr(expr)
69 }
70
71 pub struct ToStartOfHourExpr<E: Expression>(pub E);
73
74 impl<E: Expression> Expression for ToStartOfHourExpr<E> {
75 type Output = chrono::NaiveDateTime;
76
77 fn render(&self) -> String {
78 format!("toStartOfHour({})", self.0.render())
79 }
80 }
81
82 pub fn to_start_of_hour<E: Expression>(expr: E) -> ToStartOfHourExpr<E> {
83 ToStartOfHourExpr(expr)
84 }
85
86 pub struct NowExpr;
88
89 impl Expression for NowExpr {
90 type Output = chrono::NaiveDateTime;
91
92 fn render(&self) -> String {
93 "now()".to_string()
94 }
95 }
96
97 pub fn now() -> NowExpr {
98 NowExpr
99 }
100
101 pub struct TodayExpr;
103
104 impl Expression for TodayExpr {
105 type Output = chrono::NaiveDate;
106
107 fn render(&self) -> String {
108 "today()".to_string()
109 }
110 }
111
112 pub fn today() -> TodayExpr {
113 TodayExpr
114 }
115}
116
117pub mod string {
120 use super::*;
121
122 pub struct LengthExpr<E: Expression<Output = String>>(pub E);
124
125 impl<E: Expression<Output = String>> Expression for LengthExpr<E> {
126 type Output = u64;
127
128 fn render(&self) -> String {
129 format!("length({})", self.0.render())
130 }
131 }
132
133 pub fn length<E: Expression<Output = String>>(expr: E) -> LengthExpr<E> {
134 LengthExpr(expr)
135 }
136
137 pub struct LowerExpr<E: Expression<Output = String>>(pub E);
139
140 impl<E: Expression<Output = String>> Expression for LowerExpr<E> {
141 type Output = String;
142
143 fn render(&self) -> String {
144 format!("lower({})", self.0.render())
145 }
146 }
147
148 pub fn lower<E: Expression<Output = String>>(expr: E) -> LowerExpr<E> {
149 LowerExpr(expr)
150 }
151
152 pub struct UpperExpr<E: Expression<Output = String>>(pub E);
154
155 impl<E: Expression<Output = String>> Expression for UpperExpr<E> {
156 type Output = String;
157
158 fn render(&self) -> String {
159 format!("upper({})", self.0.render())
160 }
161 }
162
163 pub fn upper<E: Expression<Output = String>>(expr: E) -> UpperExpr<E> {
164 UpperExpr(expr)
165 }
166
167 pub struct ConcatExpr<A: Expression<Output = String>, B: Expression<Output = String>> {
169 a: A,
170 b: B,
171 }
172
173 impl<A: Expression<Output = String>, B: Expression<Output = String>> Expression
174 for ConcatExpr<A, B>
175 {
176 type Output = String;
177
178 fn render(&self) -> String {
179 format!("concat({}, {})", self.a.render(), self.b.render())
180 }
181 }
182
183 pub fn concat<A: Expression<Output = String>, B: Expression<Output = String>>(
184 a: A,
185 b: B,
186 ) -> ConcatExpr<A, B> {
187 ConcatExpr { a, b }
188 }
189
190 pub struct SubstringExpr<E: Expression<Output = String>> {
192 inner: E,
193 offset: usize,
194 length: usize,
195 }
196
197 impl<E: Expression<Output = String>> Expression for SubstringExpr<E> {
198 type Output = String;
199
200 fn render(&self) -> String {
201 format!(
202 "substring({}, {}, {})",
203 self.inner.render(),
204 self.offset,
205 self.length
206 )
207 }
208 }
209
210 pub fn substring<E: Expression<Output = String>>(
211 expr: E,
212 offset: usize,
213 length: usize,
214 ) -> SubstringExpr<E> {
215 SubstringExpr {
216 inner: expr,
217 offset,
218 length,
219 }
220 }
221}
222
223pub mod math {
226 use super::*;
227
228 pub struct AbsExpr<E: Expression>(pub E);
230
231 impl<E: Expression> Expression for AbsExpr<E>
232 where
233 E::Output: Numeric,
234 {
235 type Output = E::Output;
236
237 fn render(&self) -> String {
238 format!("abs({})", self.0.render())
239 }
240 }
241
242 pub fn abs<E: Expression>(expr: E) -> AbsExpr<E>
243 where
244 E::Output: Numeric,
245 {
246 AbsExpr(expr)
247 }
248
249 pub struct RoundExpr<E: Expression> {
251 inner: E,
252 precision: u8,
253 }
254
255 impl<E: Expression> Expression for RoundExpr<E>
256 where
257 E::Output: Numeric,
258 {
259 type Output = E::Output;
260
261 fn render(&self) -> String {
262 format!("round({}, {})", self.inner.render(), self.precision)
263 }
264 }
265
266 pub fn round<E: Expression>(expr: E, precision: u8) -> RoundExpr<E>
267 where
268 E::Output: Numeric,
269 {
270 RoundExpr {
271 inner: expr,
272 precision,
273 }
274 }
275
276 pub struct FloorExpr<E: Expression>(pub E);
278
279 impl<E: Expression> Expression for FloorExpr<E>
280 where
281 E::Output: Numeric,
282 {
283 type Output = E::Output;
284
285 fn render(&self) -> String {
286 format!("floor({})", self.0.render())
287 }
288 }
289
290 pub fn floor<E: Expression>(expr: E) -> FloorExpr<E>
291 where
292 E::Output: Numeric,
293 {
294 FloorExpr(expr)
295 }
296
297 pub struct CeilExpr<E: Expression>(pub E);
299
300 impl<E: Expression> Expression for CeilExpr<E>
301 where
302 E::Output: Numeric,
303 {
304 type Output = E::Output;
305
306 fn render(&self) -> String {
307 format!("ceil({})", self.0.render())
308 }
309 }
310
311 pub fn ceil<E: Expression>(expr: E) -> CeilExpr<E>
312 where
313 E::Output: Numeric,
314 {
315 CeilExpr(expr)
316 }
317
318 pub struct PowExpr<B: Expression, X: Expression> {
320 base: B,
321 exp: X,
322 }
323
324 impl<B: Expression, X: Expression> Expression for PowExpr<B, X>
325 where
326 B::Output: Numeric,
327 X::Output: Numeric,
328 {
329 type Output = f64;
330
331 fn render(&self) -> String {
332 format!("pow({}, {})", self.base.render(), self.exp.render())
333 }
334 }
335
336 pub fn pow<B: Expression, X: Expression>(base: B, exp: X) -> PowExpr<B, X>
337 where
338 B::Output: Numeric,
339 X::Output: Numeric,
340 {
341 PowExpr { base, exp }
342 }
343}
344
345pub mod conditional {
348 use super::*;
349
350 pub struct IfExpr<C, T, E>
352 where
353 C: Expression<Output = bool>,
354 T: Expression,
355 E: Expression,
356 {
357 condition: C,
358 then_expr: T,
359 else_expr: E,
360 }
361
362 impl<C, T, E> Expression for IfExpr<C, T, E>
363 where
364 C: Expression<Output = bool>,
365 T: Expression,
366 E: Expression<Output = T::Output>,
367 {
368 type Output = T::Output;
369
370 fn render(&self) -> String {
371 format!(
372 "if({}, {}, {})",
373 self.condition.render(),
374 self.then_expr.render(),
375 self.else_expr.render()
376 )
377 }
378 }
379
380 pub fn if_<C, T, E>(condition: C, then_expr: T, else_expr: E) -> IfExpr<C, T, E>
381 where
382 C: Expression<Output = bool>,
383 T: Expression,
384 E: Expression<Output = T::Output>,
385 {
386 IfExpr {
387 condition,
388 then_expr,
389 else_expr,
390 }
391 }
392}
393
394pub mod hash {
397 use super::*;
398
399 pub struct CityHash64Expr<E: Expression>(pub E);
401
402 impl<E: Expression> Expression for CityHash64Expr<E> {
403 type Output = u64;
404
405 fn render(&self) -> String {
406 format!("cityHash64({})", self.0.render())
407 }
408 }
409
410 pub fn city_hash_64<E: Expression>(expr: E) -> CityHash64Expr<E> {
411 CityHash64Expr(expr)
412 }
413
414 pub struct XxHash64Expr<E: Expression>(pub E);
416
417 impl<E: Expression> Expression for XxHash64Expr<E> {
418 type Output = u64;
419
420 fn render(&self) -> String {
421 format!("xxHash64({})", self.0.render())
422 }
423 }
424
425 pub fn xx_hash_64<E: Expression>(expr: E) -> XxHash64Expr<E> {
426 XxHash64Expr(expr)
427 }
428}