2 releases
Uses new Rust 2024
| 0.0.2 | Sep 27, 2025 |
|---|---|
| 0.0.1 | Sep 27, 2025 |
#1021 in Database interfaces
19KB
167 lines
🦸 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 (anotherRecord, a tuple, or aVec<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() {
// 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.
Dependencies
~1–18MB
~200K SLoC