Expand description
§entity-derive-impl
Procedural macro implementation for entity-derive.
This is an internal crate. Use entity-derive directly.
§Overview
This crate contains the proc-macro implementation for the #[derive(Entity)] macro.
It generates:
- DTOs (
CreateRequest,UpdateRequest,Response) - Repository traits and implementations
- Type-safe SQL queries
- Projections and filters
§Documentation
For complete documentation, examples, and usage guide, see:
- entity-derive documentation - Full API reference
- GitHub repository - Source code and examples
- Wiki - Comprehensive guides
§License
MIT License - see LICENSE
§Quick Navigation
- Getting Started: See the crate documentation above
- Derive Macro:
Entity— the main derive macro - Examples: Check the examples directory
- Wiki: Comprehensive guides
§Attribute Quick Reference
§Entity-Level #[entity(...)]
ⓘ
#[derive(Entity)]
#[entity(
table = "users", // Required: database table name
schema = "public", // Optional: database schema (default: "public")
sql = "full", // Optional: "full" | "trait" | "none" (default: "full")
dialect = "postgres", // Optional: "postgres" | "clickhouse" | "mongodb" (default: "postgres")
uuid = "v7" // Optional: "v7" | "v4" (default: "v7")
)]
pub struct User { /* ... */ }§Field-Level Attributes
ⓘ
pub struct User {
#[id] // Primary key, UUID v7, always in response
pub id: Uuid,
#[field(create, update, response)] // In all DTOs
pub name: String,
#[field(create, response)] // Create + Response only
pub email: String,
#[field(skip)] // Excluded from all DTOs
pub password_hash: String,
#[field(response)]
#[auto] // Auto-generated (excluded from create/update)
pub created_at: DateTime<Utc>,
#[belongs_to(Organization)] // Foreign key relation
pub org_id: Uuid,
#[filter] // Exact match filter in Query struct
pub status: String,
#[filter(like)] // ILIKE pattern filter
pub name: String,
#[filter(range)] // Range filter (generates from/to fields)
pub created_at: DateTime<Utc>,
}
// Projections - partial views of the entity
#[projection(Public: id, name)] // UserPublic struct
#[projection(Admin: id, name, email)] // UserAdmin struct§Generated Code Overview
For a User entity, the macro generates:
| Generated Type | Description |
|---|---|
CreateUserRequest | DTO for POST requests |
UpdateUserRequest | DTO for PATCH requests (all fields Option<T>) |
UserResponse | DTO for API responses |
UserRow | Database row mapping (for sqlx::FromRow) |
InsertableUser | Struct for INSERT statements |
UserQuery | Query struct for type-safe filtering (if #[filter] used) |
UserRepository | Async trait with CRUD methods |
impl UserRepository for PgPool | PostgreSQL implementation |
User{Projection} | Projection structs (e.g., UserPublic, UserAdmin) |
From<...> impls | Type conversions between all structs |
§SQL Generation Modes
| Mode | Generates Trait | Generates Impl | Use Case |
|---|---|---|---|
sql = "full" | ✅ | ✅ | Standard CRUD, simple queries |
sql = "trait" | ✅ | ❌ | Custom SQL (joins, CTEs, search) |
sql = "none" | ❌ | ❌ | DTOs only, no database layer |
§Repository Methods
The generated {Name}Repository trait includes:
ⓘ
#[async_trait]
pub trait UserRepository: Send + Sync {
type Error: std::error::Error + Send + Sync;
/// Create a new entity
async fn create(&self, dto: CreateUserRequest) -> Result<User, Self::Error>;
/// Find entity by primary key
async fn find_by_id(&self, id: Uuid) -> Result<Option<User>, Self::Error>;
/// Update entity with partial data
async fn update(&self, id: Uuid, dto: UpdateUserRequest) -> Result<User, Self::Error>;
/// Delete entity by primary key
async fn delete(&self, id: Uuid) -> Result<bool, Self::Error>;
/// List entities with pagination
async fn list(&self, limit: i64, offset: i64) -> Result<Vec<User>, Self::Error>;
/// Query entities with type-safe filters (if #[filter] used)
async fn query(&self, query: UserQuery) -> Result<Vec<User>, Self::Error>;
// For each projection, generates optimized SELECT method
async fn find_by_id_public(&self, id: Uuid) -> Result<Option<UserPublic>, Self::Error>;
async fn find_by_id_admin(&self, id: Uuid) -> Result<Option<UserAdmin>, Self::Error>;
}§Projections
Define partial views of entities for optimized SELECT queries:
ⓘ
#[derive(Entity)]
#[entity(table = "users")]
#[projection(Public: id, name, avatar)] // Public profile
#[projection(Admin: id, name, email, role)] // Admin view
pub struct User {
#[id]
pub id: Uuid,
#[field(create, update, response)]
pub name: String,
#[field(create, response)]
pub email: String,
#[field(update, response)]
pub avatar: Option<String>,
#[field(response)]
pub role: String,
}
// Generated: UserPublic, UserAdmin structs
// Generated: find_by_id_public, find_by_id_admin methods
// SQL: SELECT id, name, avatar FROM public.users WHERE id = $1
let public = repo.find_by_id_public(user_id).await?;§Error Handling
The generated implementation uses sqlx::Error as the error type.
You can wrap it in your application’s error type:
ⓘ
use entity_derive::Entity;
#[derive(Entity)]
#[entity(table = "users", sql = "trait")] // Generate trait only
pub struct User { /* ... */ }
// Implement with your own error type
#[async_trait]
impl UserRepository for MyDatabase {
type Error = MyAppError; // Your custom error
async fn create(&self, dto: CreateUserRequest) -> Result<User, Self::Error> {
// Your implementation
}
}§Compile-Time Guarantees
This crate provides several compile-time guarantees:
- No sensitive data leaks: Fields marked
#[field(skip)]are excluded from all DTOs - Type-safe updates:
UpdateRequestfields are properly wrapped inOption - Consistent mapping:
Fromimpls are always in sync with field definitions - SQL injection prevention: All queries use parameterized bindings
§Performance
- Zero runtime overhead: All code generation happens at compile time
- No reflection: Generated code is plain Rust structs and impls
- Minimal dependencies: Only proc-macro essentials (syn, quote, darling)
§Comparison with Alternatives
| Feature | entity-derive | Diesel | SeaORM |
|---|---|---|---|
| DTO generation | ✅ | ❌ | ❌ |
| Repository pattern | ✅ | ❌ | Partial |
| Type-safe SQL | ✅ | ✅ | ✅ |
| Async support | ✅ | Partial | ✅ |
| Boilerplate reduction | ~90% | ~50% | ~60% |
Derive Macros§
- Entity
- Derive macro for generating complete domain boilerplate from a single entity definition.
- Entity
Error - Derive macro for generating OpenAPI error response documentation.