Skip to content

nils-degroot/cinderblock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WARNING: This is far from completed. Expect many breaking changes.

Cinderblock

A declarative, resource-oriented application framework for Rust.

Define your domain model once using the resource! macro and Cinderblock generates the struct, CRUD operations, persistence layer, and REST API endpoints.

Quick Example

use cinderblock_core::{Context, resource, serde::{Deserialize, Serialize}};
use uuid::Uuid;

resource! {
    name = Helpdesk.Support.Ticket;

    attributes {
        ticket_id Uuid {
            primary_key true;
            writable false;
            default || uuid::Uuid::new_v4();
        }
        subject String;
        status TicketStatus;
    }

    actions {
        create open;
        create assign { accept [subject]; };
        update close {
            accept [];
            change_ref |ticket| {
                ticket.status = TicketStatus::Closed;
            };
        };
        destroy remove;
    }

    extensions {
        cinderblock_json_api {};
        cinderblock_sqlx { table = "tickets"; };
    }
}

This single declaration generates:

  • A Ticket struct with serialization
  • Typed action markers (Open, Assign, Close, Remove) with dedicated input structs
  • Create, Update, and Destroy trait implementations
  • REST API endpoints via Axum with OpenAPI documentation
  • SQL persistence via SQLx with parameterized queries

A complete ticketing system can be found at cinderblock-ticketing

Key Concepts

Named Actions

Actions are not generic CRUD verbs -- they are domain-specific operations with their own types and input validation:

cinderblock_core::create::<Ticket, Open>(open_input, &ctx).await?;
cinderblock_core::update::<Ticket, Close>(&ticket_id, close_input, &ctx).await?;
cinderblock_core::destroy::<Ticket, Remove>(&ticket_id, &ctx).await?;

Actions can restrict which fields they accept (accept [field1, field2]) and apply programmatic mutations via change_ref closures.

Pluggable Data Layers

  • InMemoryDataLayer (default) -- global RwLock<HashMap> for prototyping
  • SqliteDataLayer (via cinderblock-sqlx) -- full SQLite persistence using SQLx

Extension System

Extensions hook into the resource! macro to generate additional code:

extensions {
    cinderblock_json_api {};                    // REST API with OpenAPI
    cinderblock_sqlx { table = "my_table"; };   // SQL persistence
}

Crates

Crate Description
cinderblock-core Resource trait, CRUD functions, Context, in-memory data layer
cinderblock-core-macros The resource! proc macro
cinderblock-extension-api Shared DSL parser types for extension authors
cinderblock-json-api JSON REST API extension (Axum router, OpenAPI, Swagger UI)
cinderblock-json-api-macros JSON API extension proc macro
cinderblock-sqlx SQLx data layer extension (SQLite)
cinderblock-sqlx-macros SQLx extension proc macro

Running the Examples

# Core CRUD with in-memory storage
cargo run --example helpdesk -p cinderblock-core

# JSON API server with Swagger UI
cargo run --example helpdesk_api -p cinderblock-json-api --features swagger-ui

The API example starts a server on http://localhost:3000 with endpoints like:

GET    /helpdesk/support/ticket
POST   /helpdesk/support/ticket/open
PATCH  /helpdesk/support/ticket/{id}/close
DELETE /helpdesk/support/ticket/{id}/remove
GET    /openapi.json

License

Licensed under Apache-2.0.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages