cape

Crates.iocape
lib.rscape
version0.0.2
created_at2025-09-27 15:31:41.839888+00
updated_at2025-09-27 15:39:43.856301+00
description🦸 An unintrusive ORM for Rust
homepage
repositoryhttps://github.com/mcaneris/cape
max_upload_size
id1857423
size63,626
Mete Can Eriş (mcaneris)

documentation

https://docs.rs/cape

README

🦸 Cape  

⚠️ Work in Progress: This project is currently under active development and not ready for production use.

Cape is an unintrusive and lightweight wrapper ORM for Rust.

Build Status Docs Latest Version


✨ Why Cape?

Most ORMs force core domain structs to mirror database schemas — IDs, foreign keys, and boilerplate that sullies the core domain model.

Cape flips this around by wrapping the domain model, just like a superhero’s cape. Core types stay clean and focused, while persistence details live in the wrapper.


🧩 Core Concepts

Cape centers on a single generic type:

Record<T, R, S, K>
  • Tinner entity (core struct)
  • Rrelations (another Record, a tuple, or a Vec<Record>)
  • Spersistence state (N, S)
  • Kkey type (i64, Uuid, etc.)

Example

use cape::prelude::*;
use uuid::Uuid;

#[derive(Debug, Clone)]
pub struct User {
    pub username: String,
    pub email: String,
}

#[derive(Debug, Clone)]
pub struct Post {
    pub title: String,
    pub body: String,
}

fn main() {
    // New user, not yet persisted
    let new_user: Record<User, (), N, Uuid> = Record::new(User {
        username: "alice".into(),
        email: "alice@example.com".into(),
    });

    assert!(new_user.is_dirty(), true);

    // Stored user, persisted with a UUID
    let stored_user = new_user.store(Uuid::new_v4(), chrono::Utc::now().naive_utc());

    // New post with a stored author relation
    let new_post: Record<Post, Record<User, (), S, Uuid>, N, i64> =
        Record::with_relations(
            Post { title: "Hello".into(), body: "Cape world!" },
            stored_user,
        );

    // Move post into stored state
    let stored_post = new_post.store(42, chrono::Utc::now().naive_utc());

    assert!(new_user.is_dirty(), false);

    println!("Post '{}' by {}", 
        stored_post.inner.title,
        stored_post.relations.inner.username
    );
}

📜 License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Commit count: 0

cargo fmt