qraft_core/select/
project.rs1use crate::{
4 alias::Aliased,
5 count_idents,
6 expression::Expression,
7 impl_for_all_tuples,
8 lower::{Instructions, LowerCtx},
9 span::TextSpan,
10};
11
12pub trait LowerProject {
14 fn lower_project(self, ctx: &mut LowerCtx);
16}
17
18#[derive(Debug, Clone, Copy)]
20pub struct Star {
21 _priv: (),
22}
23
24pub fn star() -> Star {
26 Star { _priv: () }
27}
28
29impl LowerProject for Star {
30 fn lower_project(self, ctx: &mut LowerCtx) {
31 let _ = ctx.lower_star();
32 }
33}
34
35impl<E> LowerProject for E
36where
37 E: Expression,
38{
39 fn lower_project(self, ctx: &mut LowerCtx) {
40 let _ = self.lower(ctx);
41 }
42}
43
44impl<E> LowerProject for Aliased<E>
45where
46 E: Expression,
47{
48 fn lower_project(self, ctx: &mut LowerCtx) {
49 let inner = self.inner.lower(ctx);
50 let _ = ctx.lower_alias(self.alias, inner);
51 }
52}
53
54impl LowerProject for &'static str {
55 fn lower_project(self, ctx: &mut LowerCtx) {
56 let span = TextSpan::new_static(self);
57 ctx.instrs.push_column(None, span);
58 }
59}
60
61impl LowerProject for Aliased<&'static str> {
62 fn lower_project(self, ctx: &mut LowerCtx) {
63 self.inner.lower_project(ctx);
64 let _ = ctx.lower_alias(self.alias, 1);
65 }
66}
67
68#[derive(Debug, PartialEq, Eq, Hash)]
70pub struct ColumnOf {
71 pub table: &'static str,
73 pub name: &'static str,
75}
76
77impl ColumnOf {
78 pub const fn new(table: &'static str, name: &'static str) -> Self {
80 Self { table, name }
81 }
82}
83
84impl LowerProject for ColumnOf {
85 fn lower_project(self, ctx: &mut LowerCtx) {
86 let _ = ctx.lower_column(Some(self.table), self.name);
87 }
88}
89
90impl LowerProject for Aliased<ColumnOf> {
91 fn lower_project(self, ctx: &mut LowerCtx) {
92 self.inner.lower_project(ctx);
93 let _ = ctx.lower_alias(self.alias, 1);
94 }
95}
96
97impl<T: LowerProject, const N: usize> LowerProject for [T; N] {
98 fn lower_project(self, ctx: &mut LowerCtx) {
99 let len = self.len();
100 for item in self {
101 item.lower_project(ctx);
102 }
103 ctx.instrs.push_seperated(len);
104 }
105}
106
107impl<T: LowerProject> LowerProject for Vec<T> {
108 fn lower_project(self, ctx: &mut LowerCtx) {
109 let len = self.len();
110 for item in self {
111 item.lower_project(ctx);
112 }
113 ctx.instrs.push_seperated(len);
114 }
115}
116
117macro_rules! impl_project_macro {
120 ($($T:ident),+) => {
121 impl<$($T,)+> LowerProject for ($($T,)+)
122 where
123 $($T: LowerProject,)+
124 {
125 fn lower_project(self, ctx: &mut LowerCtx) {
126 #[allow(non_snake_case)]
127 let ($($T,)+) = self;
128 $(
129 $T.lower_project(ctx);
130 )+
131 let count = count_idents!($($T,)+);
132 ctx.instrs.push_seperated(count);
133 }
134 }
135 };
136}
137
138impl_for_all_tuples!(impl_project_macro);