qraft_core/select/
order.rs1use crate::{
4 alias::Aliased,
5 count_idents,
6 expression::Expression,
7 impl_for_all_tuples,
8 lower::{Instructions, LowerCtx},
9 query::LowerProject,
10};
11
12pub trait LowerOrderBy {
14 fn lower_order_by(self, ctx: &mut LowerCtx);
16}
17
18impl<E> LowerOrderBy for E
19where
20 E: Expression,
21{
22 fn lower_order_by(self, ctx: &mut LowerCtx) {
23 self.lower(ctx);
24 }
25}
26
27impl LowerOrderBy for &'static str {
28 fn lower_order_by(self, ctx: &mut LowerCtx) {
29 ctx.lower_table(self);
30 }
31}
32
33impl<T: LowerProject> LowerOrderBy for Aliased<T> {
34 fn lower_order_by(self, ctx: &mut LowerCtx) {
35 ctx.lower_table(self.alias);
36 }
37}
38
39pub trait Order: Sized {
41 fn asc(self) -> OrderNode<Self>;
43 fn desc(self) -> OrderNode<Self>;
45}
46
47impl<E> Order for E
48where
49 E: LowerOrderBy,
50{
51 fn asc(self) -> OrderNode<Self> {
52 OrderNode {
53 inner: self,
54 kind: SortKind::Asc,
55 }
56 }
57
58 fn desc(self) -> OrderNode<Self> {
59 OrderNode {
60 inner: self,
61 kind: SortKind::Desc,
62 }
63 }
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub enum SortKind {
69 Asc,
70 Desc,
71}
72
73#[derive(Debug, Clone, Copy, PartialEq, Eq)]
75pub struct OrderNode<E> {
76 kind: SortKind,
77 inner: E,
78}
79
80impl<E> LowerOrderBy for OrderNode<E>
81where
82 E: LowerOrderBy,
83{
84 fn lower_order_by(self, ctx: &mut LowerCtx) {
85 self.inner.lower_order_by(ctx);
86 let _ = ctx.lower_order_by(self.kind, 1);
87 }
88}
89
90macro_rules! impl_orderby_macro {
91 ($($T:ident),+) => {
92 impl<$($T,)+> LowerOrderBy for ($($T,)+)
93 where
94 $($T: LowerOrderBy,)+
95 {
96 fn lower_order_by(self, ctx: &mut LowerCtx) {
97 #[allow(non_snake_case)]
98 let ($($T,)+) = self;
99 $(
100 $T.lower_order_by(ctx);
101 )+
102 let count = count_idents!($($T,)+);
103 ctx.instrs.push_seperated(count);
104 }
105 }
106 };
107}
108
109impl_for_all_tuples!(impl_orderby_macro);