cratestack-macros
Procedural macros for compile-time schema processing.
Overview
cratestack-macros exposes three role-specific proc-macros that parse a .cstack file at compile time and emit Rust code inside a cratestack_schema module. Each macro maps to a deployment shape:
| Macro | Deployment shape | Emits |
|---|---|---|
include_server_schema! |
Server (Postgres via sqlx) | full ORM + axum router + procedures + events + sqlx FromRow |
include_embedded_schema! |
Embedded ORM (mobile / desktop / browser via OPFS) | model structs + descriptors + rusqlite FromRow + inputs |
include_client_schema! |
HTTP client (talks to a server, owns no DB) | model/input/procedure stubs, no DB |
The split is strict: include_server_schema! never emits rusqlite items, include_embedded_schema! never emits sqlx items. Each deployment pays only for its own surface.
All three are re-exported through the facade crates cratestack-pg and cratestack-sqlite; most consumers should depend on one of those (renamed to cratestack via Cargo's package = field) rather than this crate directly. The choice of facade picks which side of the strict split the macro emits against — backend services use cratestack-pg, embedded / mobile / wasm builds use cratestack-sqlite.
Installation
[]
# Server-side
= { = "cratestack-pg", = "0.4" }
# OR embedded-side
# cratestack = { package = "cratestack-sqlite", version = "0.4" }
include_server_schema!
use include_server_schema;
include_server_schema!;
let pool = connect.await?;
let cool = builder.build;
Only db = Postgres is currently accepted. The parser is wired so adding MySql / Sqlite-via-sqlx in a future release is non-breaking at call sites that already pass db = Postgres.
The macro emits, inside a cratestack_schema module:
- model structs +
sqlx::FromRow<PgRow>impls for eachmodel Create<Model>InputandUpdate<Model>Inputstructs- per-model selection / include builders
- per-model filter/order helper modules (e.g.
cratestack_schema::post::published()) - the
Cratestackruntime struct withbuilder(pool),bind_context(ctx),bind_auth(principal), and per-model accessors (cool.post(),cool.user(), ...) axum::model_router(cool, codec, auth_provider)andaxum::procedure_router(...)- procedure dispatch glue and
events::Subscriptionsfor@@emitmodel events - for each
viewblock: a typed struct,<UPPER>_VIEW: ViewDescriptor<...>const,sqlx::FromRow<PgRow>impl, and an accessor oncool.views().<view_snake>()returningViewDelegate(orViewDelegateNoUniquefor@@no_uniqueviews).@@materializedviews also get arefresh()method. See ADR-0003.
include_embedded_schema!
use include_embedded_schema;
use ;
include_embedded_schema!;
let runtime = open?;
runtime.with_connection?;
let notes = new;
The macro emits:
- model structs +
cratestack_rusqlite::FromRusqliteRowimpls ModelDescriptorconstants (needed byModelDelegate)Create<Model>Input/Update<Model>InputwithCreateModelInput/UpdateModelInputimpls- per-model filter helper modules
- for each non-
@@materializedviewblock: a typed struct,<UPPER>_VIEW: ViewDescriptor<...>const, andcratestack_rusqlite::FromRusqliteRowimpl.@@materializedviews are rejected at expansion time with acompile_error!referencing ADR-0003 — SQLite has no materialized views.
It does not emit: sqlx::FromRow, the Cratestack server runtime, axum routes, procedure handlers, or events. Policies (@@allow / @@deny) are silently dropped — clients are untrusted; authorization is the server's job.
@@audit and @@emit directives are currently no-ops in this macro. The local-journal / local-event-bus implementations land in a follow-up release.
include_client_schema!
Emits a strict subset of the server surface — model and input types, enums, selection/projection helpers, and the client::Client wrapper — with no SQLx or Axum integration. Renamed from include_client_macro! in 0.3.0.
use include_client_schema;
include_client_schema!;
Migration from 0.2.x
include_schema! and include_client_macro! were removed in 0.3.0. Migrate:
| Before | After |
|---|---|
include_schema!("schema.cstack"); (server context) |
include_server_schema!("schema.cstack", db = Postgres); |
include_schema!("schema.cstack"); (sqlite/embedded context) |
include_embedded_schema!("schema.cstack"); |
include_client_macro!("schema.cstack"); |
include_client_schema!("schema.cstack"); |
See the workspace CHANGELOG.md for full release notes.
Decimal Backend
Generated code references cratestack::Decimal, which resolves at compile time to either rust_decimal::Decimal (decimal-rust-decimal, default) or the reserved decimal-bigdecimal backend.
See Also
cratestack— facade crate that re-exports the macroscratestack-parser— the parser the macros call- Quickstart
License
MIT