🦸 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.

✨ 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>
T → inner entity (core struct)
R → relations (another Record, a tuple, or a Vec<Record>)
S → persistence state (N, S)
K → key 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() {
let new_user: Record<User, (), N, Uuid> = Record::new(User {
username: "alice".into(),
email: "alice@example.com".into(),
});
assert!(new_user.is_dirty(), true);
let stored_user = new_user.store(Uuid::new_v4(), chrono::Utc::now().naive_utc());
let new_post: Record<Post, Record<User, (), S, Uuid>, N, i64> =
Record::with_relations(
Post { title: "Hello".into(), body: "Cape world!" },
stored_user,
);
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