Skip to main content

qcraft_core/render/
renderer.rs

1use crate::ast::common::OrderByDef;
2use crate::ast::conditions::{CompareOp, Conditions};
3use crate::ast::ddl::{ColumnDef, ConstraintDef, FieldType, IndexDef, SchemaMutationStmt};
4use crate::ast::dml::{DeleteStmt, InsertStmt, MutationStmt, OnConflictDef, UpdateStmt};
5use crate::ast::expr::{AggregationDef, CaseDef, Expr, WindowDef};
6use crate::ast::query::{
7    CteDef, JoinDef, LimitDef, QueryStmt, SelectColumn, SelectLockDef, TableSource,
8};
9use crate::ast::tcl::TransactionStmt;
10use crate::error::RenderResult;
11use crate::render::ctx::RenderCtx;
12
13/// The core rendering trait. Each dialect implements this.
14///
15/// Users can wrap a dialect renderer and override individual methods
16/// to customize behavior.
17pub trait Renderer {
18    // ── Top-level ──
19
20    fn render_query(&self, stmt: &QueryStmt, ctx: &mut RenderCtx) -> RenderResult<()>;
21    fn render_mutation(&self, stmt: &MutationStmt, ctx: &mut RenderCtx) -> RenderResult<()>;
22    fn render_schema_mutation(
23        &self,
24        stmt: &SchemaMutationStmt,
25        ctx: &mut RenderCtx,
26    ) -> RenderResult<()>;
27    fn render_transaction(&self, stmt: &TransactionStmt, ctx: &mut RenderCtx) -> RenderResult<()>;
28
29    // ── SELECT parts ──
30
31    fn render_select_columns(&self, cols: &[SelectColumn], ctx: &mut RenderCtx)
32    -> RenderResult<()>;
33    fn render_from(&self, source: &TableSource, ctx: &mut RenderCtx) -> RenderResult<()>;
34    fn render_joins(&self, joins: &[JoinDef], ctx: &mut RenderCtx) -> RenderResult<()>;
35    fn render_where(&self, cond: &Conditions, ctx: &mut RenderCtx) -> RenderResult<()>;
36    fn render_order_by(&self, order: &[OrderByDef], ctx: &mut RenderCtx) -> RenderResult<()>;
37    fn render_limit(&self, limit: &LimitDef, ctx: &mut RenderCtx) -> RenderResult<()>;
38    fn render_ctes(&self, ctes: &[CteDef], ctx: &mut RenderCtx) -> RenderResult<()>;
39    fn render_lock(&self, lock: &SelectLockDef, ctx: &mut RenderCtx) -> RenderResult<()>;
40
41    // ── Expressions ──
42
43    fn render_expr(&self, expr: &Expr, ctx: &mut RenderCtx) -> RenderResult<()>;
44    fn render_aggregate(&self, agg: &AggregationDef, ctx: &mut RenderCtx) -> RenderResult<()>;
45    fn render_window(&self, win: &WindowDef, ctx: &mut RenderCtx) -> RenderResult<()>;
46    fn render_case(&self, case: &CaseDef, ctx: &mut RenderCtx) -> RenderResult<()>;
47
48    // ── Conditions ──
49
50    fn render_condition(&self, cond: &Conditions, ctx: &mut RenderCtx) -> RenderResult<()>;
51    fn render_compare_op(
52        &self,
53        op: &CompareOp,
54        left: &Expr,
55        right: &Expr,
56        ctx: &mut RenderCtx,
57    ) -> RenderResult<()>;
58
59    // ── DML parts ──
60
61    fn render_insert(&self, stmt: &InsertStmt, ctx: &mut RenderCtx) -> RenderResult<()>;
62    fn render_update(&self, stmt: &UpdateStmt, ctx: &mut RenderCtx) -> RenderResult<()>;
63    fn render_delete(&self, stmt: &DeleteStmt, ctx: &mut RenderCtx) -> RenderResult<()>;
64    fn render_on_conflict(&self, oc: &OnConflictDef, ctx: &mut RenderCtx) -> RenderResult<()>;
65    fn render_returning(&self, cols: &[SelectColumn], ctx: &mut RenderCtx) -> RenderResult<()>;
66
67    // ── DDL parts ──
68
69    fn render_column_def(&self, col: &ColumnDef, ctx: &mut RenderCtx) -> RenderResult<()>;
70    fn render_column_type(&self, ty: &FieldType, ctx: &mut RenderCtx) -> RenderResult<()>;
71    fn render_constraint(&self, c: &ConstraintDef, ctx: &mut RenderCtx) -> RenderResult<()>;
72    fn render_index_def(&self, idx: &IndexDef, ctx: &mut RenderCtx) -> RenderResult<()>;
73}
74
75/// Macro to delegate all Renderer methods to an inner renderer.
76///
77/// Usage:
78/// ```ignore
79/// struct MyRenderer { inner: PostgresRenderer }
80/// impl Renderer for MyRenderer {
81///     fn render_cast(&self, ...) { /* custom */ }
82///     delegate_renderer!(self.inner);
83/// }
84/// ```
85#[macro_export]
86macro_rules! delegate_renderer {
87    ($self:ident . $inner:ident) => {
88        fn render_query(
89            &$self,
90            stmt: &$crate::ast::query::QueryStmt,
91            ctx: &mut $crate::render::ctx::RenderCtx,
92        ) -> $crate::error::RenderResult<()> {
93            $self.$inner.render_query(stmt, ctx)
94        }
95        fn render_mutation(
96            &$self,
97            stmt: &$crate::ast::dml::MutationStmt,
98            ctx: &mut $crate::render::ctx::RenderCtx,
99        ) -> $crate::error::RenderResult<()> {
100            $self.$inner.render_mutation(stmt, ctx)
101        }
102        fn render_schema_mutation(
103            &$self,
104            stmt: &$crate::ast::ddl::SchemaMutationStmt,
105            ctx: &mut $crate::render::ctx::RenderCtx,
106        ) -> $crate::error::RenderResult<()> {
107            $self.$inner.render_schema_mutation(stmt, ctx)
108        }
109        fn render_transaction(
110            &$self,
111            stmt: &$crate::ast::tcl::TransactionStmt,
112            ctx: &mut $crate::render::ctx::RenderCtx,
113        ) -> $crate::error::RenderResult<()> {
114            $self.$inner.render_transaction(stmt, ctx)
115        }
116        fn render_select_columns(
117            &$self,
118            cols: &[$crate::ast::query::SelectColumn],
119            ctx: &mut $crate::render::ctx::RenderCtx,
120        ) -> $crate::error::RenderResult<()> {
121            $self.$inner.render_select_columns(cols, ctx)
122        }
123        fn render_from(
124            &$self,
125            source: &$crate::ast::query::TableSource,
126            ctx: &mut $crate::render::ctx::RenderCtx,
127        ) -> $crate::error::RenderResult<()> {
128            $self.$inner.render_from(source, ctx)
129        }
130        fn render_joins(
131            &$self,
132            joins: &[$crate::ast::query::JoinDef],
133            ctx: &mut $crate::render::ctx::RenderCtx,
134        ) -> $crate::error::RenderResult<()> {
135            $self.$inner.render_joins(joins, ctx)
136        }
137        fn render_where(
138            &$self,
139            cond: &$crate::ast::conditions::Conditions,
140            ctx: &mut $crate::render::ctx::RenderCtx,
141        ) -> $crate::error::RenderResult<()> {
142            $self.$inner.render_where(cond, ctx)
143        }
144        fn render_order_by(
145            &$self,
146            order: &[$crate::ast::common::OrderByDef],
147            ctx: &mut $crate::render::ctx::RenderCtx,
148        ) -> $crate::error::RenderResult<()> {
149            $self.$inner.render_order_by(order, ctx)
150        }
151        fn render_limit(
152            &$self,
153            limit: &$crate::ast::query::LimitDef,
154            ctx: &mut $crate::render::ctx::RenderCtx,
155        ) -> $crate::error::RenderResult<()> {
156            $self.$inner.render_limit(limit, ctx)
157        }
158        fn render_ctes(
159            &$self,
160            ctes: &[$crate::ast::query::CteDef],
161            ctx: &mut $crate::render::ctx::RenderCtx,
162        ) -> $crate::error::RenderResult<()> {
163            $self.$inner.render_ctes(ctes, ctx)
164        }
165        fn render_lock(
166            &$self,
167            lock: &$crate::ast::query::SelectLockDef,
168            ctx: &mut $crate::render::ctx::RenderCtx,
169        ) -> $crate::error::RenderResult<()> {
170            $self.$inner.render_lock(lock, ctx)
171        }
172        fn render_expr(
173            &$self,
174            expr: &$crate::ast::expr::Expr,
175            ctx: &mut $crate::render::ctx::RenderCtx,
176        ) -> $crate::error::RenderResult<()> {
177            $self.$inner.render_expr(expr, ctx)
178        }
179        fn render_aggregate(
180            &$self,
181            agg: &$crate::ast::expr::AggregationDef,
182            ctx: &mut $crate::render::ctx::RenderCtx,
183        ) -> $crate::error::RenderResult<()> {
184            $self.$inner.render_aggregate(agg, ctx)
185        }
186        fn render_window(
187            &$self,
188            win: &$crate::ast::expr::WindowDef,
189            ctx: &mut $crate::render::ctx::RenderCtx,
190        ) -> $crate::error::RenderResult<()> {
191            $self.$inner.render_window(win, ctx)
192        }
193        fn render_case(
194            &$self,
195            case: &$crate::ast::expr::CaseDef,
196            ctx: &mut $crate::render::ctx::RenderCtx,
197        ) -> $crate::error::RenderResult<()> {
198            $self.$inner.render_case(case, ctx)
199        }
200        fn render_condition(
201            &$self,
202            cond: &$crate::ast::conditions::Conditions,
203            ctx: &mut $crate::render::ctx::RenderCtx,
204        ) -> $crate::error::RenderResult<()> {
205            $self.$inner.render_condition(cond, ctx)
206        }
207        fn render_compare_op(
208            &$self,
209            op: &$crate::ast::conditions::CompareOp,
210            left: &$crate::ast::expr::Expr,
211            right: &$crate::ast::expr::Expr,
212            ctx: &mut $crate::render::ctx::RenderCtx,
213        ) -> $crate::error::RenderResult<()> {
214            $self.$inner.render_compare_op(op, left, right, ctx)
215        }
216        fn render_insert(
217            &$self,
218            stmt: &$crate::ast::dml::InsertStmt,
219            ctx: &mut $crate::render::ctx::RenderCtx,
220        ) -> $crate::error::RenderResult<()> {
221            $self.$inner.render_insert(stmt, ctx)
222        }
223        fn render_update(
224            &$self,
225            stmt: &$crate::ast::dml::UpdateStmt,
226            ctx: &mut $crate::render::ctx::RenderCtx,
227        ) -> $crate::error::RenderResult<()> {
228            $self.$inner.render_update(stmt, ctx)
229        }
230        fn render_delete(
231            &$self,
232            stmt: &$crate::ast::dml::DeleteStmt,
233            ctx: &mut $crate::render::ctx::RenderCtx,
234        ) -> $crate::error::RenderResult<()> {
235            $self.$inner.render_delete(stmt, ctx)
236        }
237        fn render_on_conflict(
238            &$self,
239            oc: &$crate::ast::dml::OnConflictDef,
240            ctx: &mut $crate::render::ctx::RenderCtx,
241        ) -> $crate::error::RenderResult<()> {
242            $self.$inner.render_on_conflict(oc, ctx)
243        }
244        fn render_returning(
245            &$self,
246            cols: &[$crate::ast::query::SelectColumn],
247            ctx: &mut $crate::render::ctx::RenderCtx,
248        ) -> $crate::error::RenderResult<()> {
249            $self.$inner.render_returning(cols, ctx)
250        }
251        fn render_column_def(
252            &$self,
253            col: &$crate::ast::ddl::ColumnDef,
254            ctx: &mut $crate::render::ctx::RenderCtx,
255        ) -> $crate::error::RenderResult<()> {
256            $self.$inner.render_column_def(col, ctx)
257        }
258        fn render_column_type(
259            &$self,
260            ty: &$crate::ast::ddl::FieldType,
261            ctx: &mut $crate::render::ctx::RenderCtx,
262        ) -> $crate::error::RenderResult<()> {
263            $self.$inner.render_column_type(ty, ctx)
264        }
265        fn render_constraint(
266            &$self,
267            c: &$crate::ast::ddl::ConstraintDef,
268            ctx: &mut $crate::render::ctx::RenderCtx,
269        ) -> $crate::error::RenderResult<()> {
270            $self.$inner.render_constraint(c, ctx)
271        }
272        fn render_index_def(
273            &$self,
274            idx: &$crate::ast::ddl::IndexDef,
275            ctx: &mut $crate::render::ctx::RenderCtx,
276        ) -> $crate::error::RenderResult<()> {
277            $self.$inner.render_index_def(idx, ctx)
278        }
279    };
280}