resource-model-macro
A Rust proc-macro that generates complete CRUD data layers from a YAML spec — structs, SQL migrations, repository traits with sqlx implementations, and optionally a REST API via Axum + utoipa.
Define your data model once. Get a fully-typed Postgres backend at compile time.
Quick start
# Cargo.toml
[]
= "0.1"
# peer dependencies (used by generated code)
= { = "0.8", = ["runtime-tokio", "tls-rustls", "postgres", "uuid"] }
= { = "1", = ["v4", "serde"] }
= { = "1", = ["derive"] }
= "1"
= "0.1"
= { = "1", = ["full"] }
# only needed when config.api = true
= "0.8"
= { = "5", = ["uuid"] }
= "0.2"
Usage
Inline YAML
resource_model!;
From a YAML file
resource_model_file!;
The path is relative to the crate root (CARGO_MANIFEST_DIR).
What gets generated
For each entity in the spec the macro expands to:
| Generated item | Description |
|---|---|
struct User |
Row type with sqlx::FromRow, Serialize, Deserialize (and ToSchema when api: true) |
struct CreateUser |
Input type for inserts (no id field) |
struct UpdateUser |
Partial-update type (all fields Option<T>, uses COALESCE in SQL) |
trait UserRepository |
Extends CrudRepository with relation accessors |
struct SqlxUserRepository |
Concrete implementation backed by sqlx::PgPool |
async fn migrate(pool) |
Drops and recreates all tables in dependency order |
When config.api is true, a resource_api module is also generated containing:
- Axum handler functions for each CRUD endpoint and relation
- OpenAPI metadata via
utoipa::pathattributes resource_api::router() -> OpenApiRouter<PgPool>to mount everything
YAML spec format
version: 1 # must be 1
config:
visibility: "pub" # "pub", "pub(crate)", or ""
backend: "postgres" # only "postgres" supported today
api: true # optional, generates REST API module
entities:
- name: "Organization"
table: "organizations"
id:
fields:
-
-
-
- name: "User"
table: "users"
id:
fields:
-
-
- name: "org_id"
type: "uuid"
required: true
references:
relations:
-
-
Supported field types
| YAML type | Rust type | SQL type |
|---|---|---|
uuid |
uuid::Uuid |
UUID |
string |
String |
TEXT |
text |
String |
TEXT |
int |
i32 |
INTEGER |
bigint |
i64 |
BIGINT |
float |
f64 |
DOUBLE PRECISION |
bool |
bool |
BOOLEAN |
Relation kinds
| Kind | Direction | Generated method returns |
|---|---|---|
has_many |
source → target[] | Vec<Target> |
belongs_to |
source → target | Option<Target> |
Compile-time validation
The macro validates the spec before code generation and emits compile_error! for:
- Unsupported
versionorbackend - Duplicate entity / table / field names
- Unknown field types
- References pointing to nonexistent entities or fields
- Relations with missing foreign keys on the expected side
Example: wiring into Axum
use Router;
resource_model_file!;
async
Minimum supported Rust version
Rust edition 2024 (nightly or stable 1.85+).
License
See LICENSE for details.