Conversation
Add a small line-oriented `Block` builder and migrate the worst offenders in the codegen modules away from `<>` chains with embedded `\n` and hand-rolled indentation. - New `src/sqlode/codegen/builder.gleam` exposes an opaque `Block` wrapping `List(String)` with `line`, `lines`, `empty`, `blank`, `concat`, `indent`, and `render`. Blank lines never gain trailing whitespace from `indent`, keeping generated code lint-clean. - `common.gleam::gleam_type` / `gleam_fn` emit their type/function skeletons through `builder.concat` instead of embedding `\n` in string literals. - `models.gleam::render_enum_type` uses `builder.indent` for the constructor and case-branch indentation that used to be hand-rolled with `" "` / `" "` prefixes. Table/row type and alias renderers are also reduced to `builder.concat` blocks. - `adapter.gleam::render_decoder`, `render_adapter_query_result`, `render_adapter_exec`, `render_adapter_exec_rows`, and `render_adapter_exec_last_id` now compose their output via `builder.concat`. Extract `query_fn_signature` so the shared `pub fn name(db: ...) -> Result(...)` line lives in one place. - New `test/codegen_builder_test.gleam` covers empty / line / lines / blank / concat / indent / render and pins `indent(blank)` behaviour. Clean list-of-sections assembly (conditional imports, top-level `string.join(list.flatten([...]))`) is left as-is — that idiom is the mental model Block is built on, and rewriting it adds churn without readability gains. Closes #310
ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Free Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis change introduces a new code generation builder module ( Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
Summary
Introduce a small line-oriented
Blockbuilder (src/sqlode/codegen/builder.gleam) and migrate the worst<>chains incommon.gleam,models.gleam, andadapter.gleamoff of embedded-\n/ hand-rolled\" \"indentation. The goal is readability — the generated output is byte-for-byte identical, as verified by the existing substring assertions, shellspec CLI tests, and integration tests.Changes
src/sqlode/codegen/builder.gleam(new): opaqueBlockwrappingList(String)withline,lines,empty,blank,concat,indent, andrender.indentleaves blank lines empty so generated code never has trailing whitespace.test/codegen_builder_test.gleam(new): unit tests for each primitive, pinningindent(blank)behaviour.src/sqlode/codegen/common.gleam:gleam_typeandgleam_fncompose throughbuilder.concatinstead of embedding\nin string literals.src/sqlode/codegen/models.gleam:render_enum_typenow usesbuilder.indentfor constructor / case-branch indentation;render_table_type,render_row_type,render_row_type_or_alias,render_semantic_type_aliases, andrender_strong_type_wrapperscollapse their multi-linestring.joinbodies intobuilder.concatblocks.src/sqlode/codegen/adapter.gleam:render_decoder,render_adapter_query_result,render_adapter_exec,render_adapter_exec_rows, andrender_adapter_exec_last_idnow compose viabuilder.concat. Extractquery_fn_signatureso the sharedpub fn name(db: ...) -> Result(...)line lives in one place.Design Decisions
Docwith soft breaks — generated Gleam is layout-deterministic and has no reflow requirement. A flatList(String)model is what the codebase already uses (string.join(list.flatten([...]), \"\\n\"));Blockjust centralises it.string.join(list.flatten([...]), \"\\n\")) untouched. Block is modelled on that idiom, so rewriting it would add churn without improving readability.render_field_decode_lineas a one-line<>chain — it produces a single string with no\n, so the builder would only add noise.gleam_typeandgleam_fnkeep their existingString-returning signatures; they just render through a builder internally. Callers don't change.Limitations
builder.gleamlives undersrc/sqlode/codegen/, which is effectively internal to the sqlode binary (no external imports). It is not added todoc/capabilities.md.BlockAPI is minimal; richer helpers (e.g.,gleam_fn_block,gleam_type_block) could be added later if follow-up refactors want a more declarative form.Closes #310
Summary by CodeRabbit
Refactor
Tests