rust-db-blueprint 0.1.0

A Rust code generator — reads YAML draft files and generates Axum + SQLx models, migrations, handlers, routes, requests, tests, and seeds
Documentation

Laravel Blueprint

A code generation tool that reads a YAML draft file and generates Rust (Axum + SQLx) project code — models, SQL migrations, handlers, routes, request structs, test helpers, and seeds.

Written in Rust. Generates Rust.

Installation

cargo install laravel-blueprint

Quick Start

blueprint init
# edit draft.yaml...
blueprint build

Generated output

src/
├── models/
│   ├── mod.rs
│   ├── post.rs          # SQLx FromRow struct + query methods + relationship helpers
│   └── user.rs
├── handlers/
│   ├── mod.rs
│   ├── post.rs          # Axum handler functions
│   └── user.rs
├── routes.rs             # Axum Router definition
├── requests/             # Validated request DTOs
└── db/
    ├── factories.rs      # Test helper functions
    └── seeds.rs          # Database seed functions
migrations/
├── 20260528_posts.sql
└── 20260528_users.sql
tests/
├── post_test.rs
└── user_test.rs

Draft YAML Reference

Models with Relationships

models:
  Post:
    title: string:200
    content: text
    published_at: datetime nullable
    author_id: unsignedBigInteger
    relationships:
      belongsTo: User
      hasMany: Comment
      belongsToMany: Tag

  User:
    name: string:100
    email: string:100 unique
    password: string:100
    relationships:
      hasMany: Post

  Comment:
    content: text
    post_id: unsignedBigInteger
    relationships:
      belongsTo: Post

  Tag:
    name: string:50 unique

Data Types

string, text, longtext, integer, bigInteger, unsignedInteger, unsignedBigInteger, boolean, float, double, decimal, date, datetime, timestamp, json, jsonb, uuid, ipAddress, and more.

Modifiers

nullable, unique, unsigned, default:value, foreign:table.col, onDelete:cascade, autoIncrement.

Relationship Types

Type Generated helper SQL
belongsTo: User fetch_user(&self, pool) -> Result<User> SELECT * FROM users WHERE id = $1
hasMany: Comment fetch_comments(&self, pool) -> Result<Vec<Comment>> SELECT * FROM comments WHERE post_id = $1
hasOne: Profile fetch_profile(&self, pool) -> Result<Option<Profile>> SELECT * FROM profiles WHERE user_id = $1
belongsToMany: Tag fetch_tags(&self, pool) -> Result<Vec<Tag>> SELECT tags.* FROM tags INNER JOIN ...

Columns ending in _id (e.g. author_id) auto-detect belongsTo and generate both a foreign key in SQL and a fetch_author() helper.

Controllers

controllers:
  Post:
    resource: web     # Generates index, create, store, show, edit, update, destroy handlers
  User:
    resource: api     # Generates index, store, show, update, destroy handlers

Seeders

seeders:
  - Post
  - User

CLI Commands

blueprint build                       # generate all code from draft.yaml
blueprint build --only models         # only generate models
blueprint build --skip migrations     # skip migrations
blueprint build --output ./my-app     # custom output directory
blueprint init                        # create starter draft.yaml
blueprint list                        # list available generators

Generated Code Examples

Model (src/models/post.rs)

use serde::{Deserialize, Serialize};
use sqlx::FromRow;

#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
pub struct Post {
    pub id: i32,
    pub title: String,
    pub content: String,
    pub published_at: Option<chrono::NaiveDateTime>,
    pub author_id: i32,
    pub created_at: chrono::NaiveDateTime,
    pub updated_at: chrono::NaiveDateTime,
}

impl Post {
    pub async fn find_by_id(id: i32, pool: &sqlx::PgPool) -> Result<Self, sqlx::Error> { ... }
    pub async fn find_all(pool: &sqlx::PgPool) -> Result<Vec<Self>, sqlx::Error> { ... }
    pub async fn delete(self, pool: &sqlx::PgPool) -> Result<_, sqlx::Error> { ... }
    pub async fn fetch_author(&self, pool: &sqlx::PgPool) -> Result<User, sqlx::Error> { ... }
    pub async fn fetch_comments(&self, pool: &sqlx::PgPool) -> Result<Vec<Comment>, sqlx::Error> { ... }
    pub async fn fetch_tags(&self, pool: &sqlx::PgPool) -> Result<Vec<Tag>, sqlx::Error> { ... }
}

Migration (migrations/20260528_posts.sql)

CREATE TABLE posts (
    id SERIAL PRIMARY KEY,
    title VARCHAR(200) NOT NULL,
    content TEXT NOT NULL,
    published_at TIMESTAMP,
    author_id BIGINT NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
    FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE CASCADE
);

Development

git clone https://github.com/danangprasetyo/blueprint.git
cd blueprint
cargo build
cargo test

License

MIT