Crate entity_derive_impl

Crate entity_derive_impl 

Source
Expand description

§entity-derive-impl

Crates.io Docs.rs License: MIT

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:

§License

MIT License - see LICENSE

§Quick Navigation

§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 TypeDescription
CreateUserRequestDTO for POST requests
UpdateUserRequestDTO for PATCH requests (all fields Option<T>)
UserResponseDTO for API responses
UserRowDatabase row mapping (for sqlx::FromRow)
InsertableUserStruct for INSERT statements
UserQueryQuery struct for type-safe filtering (if #[filter] used)
UserRepositoryAsync trait with CRUD methods
impl UserRepository for PgPoolPostgreSQL implementation
User{Projection}Projection structs (e.g., UserPublic, UserAdmin)
From<...> implsType conversions between all structs

§SQL Generation Modes

ModeGenerates TraitGenerates ImplUse 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: UpdateRequest fields are properly wrapped in Option
  • Consistent mapping: From impls 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

Featureentity-deriveDieselSeaORM
DTO generation
Repository patternPartial
Type-safe SQL
Async supportPartial
Boilerplate reduction~90%~50%~60%

Derive Macros§

Entity
Derive macro for generating complete domain boilerplate from a single entity definition.
EntityError
Derive macro for generating OpenAPI error response documentation.