| Crates.io | rusticx_derive |
| lib.rs | rusticx_derive |
| version | 0.1.2 |
| created_at | 2025-05-12 19:47:21.885651+00 |
| updated_at | 2025-05-14 10:47:03.51626+00 |
| description | Derive macros for Rusticx ORM |
| homepage | |
| repository | https://github.com/TarunVishwakarma1/rustix-orm |
| max_upload_size | |
| id | 1671045 |
| size | 48,095 |
rusticx-derive is a procedural macro crate that provides the #[derive(Model)] attribute for the rusticx ORM. This macro automatically generates the necessary SQLModel trait implementation for your Rust structs, enabling them to be easily mapped to database tables.
Writing database mapping code manually can be repetitive and error-prone. The #[derive(Model)] macro automates this process by inspecting your struct definition and its attributes to generate:
CREATE TABLE statement, including column definitions, constraints, and defaults.INSERT or UPDATE).This allows you to define your database models in a declarative way using standard Rust structs and attributes, reducing boilerplate code and potential errors.
Add rusticx-derive and the main rusticx crate to your Cargo.toml. Remember to enable the feature flags for the database drivers you intend to use in the rusticx crate (e.g., "postgres", "mysql", "rusqlite").
[dependencies]
rusticx = { version = "x.y.z", features = ["<database-driver>"] } # Replace x.y.z with the actual version and specify features
rusticx-derive = "x.y.z" # Replace x.y.z with the actual version
serde = { version = "1.0", features = ["derive"] } # Required for deserialization
serde_json = "1.0" # Required for row deserialization via JSON
# Add uuid and chrono if you use Uuid or date/time types in your models
# uuid = { version = "1.0", features = ["serde", "v4"] }
# chrono = { version = "0.4", features = ["serde"] }
Apply the #[derive(Model)] attribute to your struct definition. Your struct must have named fields. You can customize the table name and field mappings using #[model(...)] attributes on the struct and its fields. The struct typically needs to derive serde::Deserialize for the from_row method generated by the macro.
use rusticx_derive::Model;
use serde::{Serialize, Deserialize};
use uuid::Uuid; // Example using uuid crate
use chrono::NaiveDateTime; // Example using chrono crate
#[derive(Model, Debug, Serialize, Deserialize)]
#[model(table = "my_application_users")] // Optional: Customize table name
struct User {
#[model(primary_key, auto_increment)] // Marks 'id' as primary key with auto-increment
id: Option<i32>, // Use Option<i32> for nullable auto-increment PKs
#[model(column = "username")] // Optional: Specify a custom column name
name: String, // Maps to a text/varchar column
#[model(nullable)] // Explicitly marks the 'email' column as nullable
email: Option<String>, // Option<T> fields are automatically treated as nullable
#[model(default = "'pending'")] // Sets a SQL default value (note the single quotes for the string literal)
status: String,
#[model(sql_type = "JSONB")] // Specify a custom SQL data type
metadata: serde_json::Value, // serde_json::Value maps well to JSON/JSONB types
#[model(skip)] // This field will be ignored by the ORM
transient_data: String,
#[model(primary_key, uuid)] // Alternative primary key: UUID with default generation (only one PK per struct!)
// user_uuid: Uuid, // Use Uuid or Option<Uuid> for UUID primary keys
created_at: NaiveDateTime, // Maps to an appropriate DateTime/Timestamp type
}
The #[derive(Model)] macro recognizes #[model(...)] attributes on the struct and its fields.
#[model(...)] on the struct)#[model(table = "custom_name")]: Specifies the database table name for this model. If omitted, the macro defaults to the struct name converted to lowercase and pluralized (e.g., User -> users).#[model(...)] on fields)#[model(primary_key)]: Designates this field as the primary key for the table. Exactly one field should be marked with this attribute.#[model(column = "custom_name")]: Specifies the database column name for this field. If omitted, the macro defaults to the field name converted to lowercase.#[model(default = "SQL_DEFAULT_VALUE")]: Sets a SQL DEFAULT constraint for the column. The value provided inside the quotes is inserted directly into the CREATE TABLE statement. Ensure the value is correctly formatted for SQL (e.g., enclose string literals in single quotes: "'active'").#[model(nullable)]: Explicitly marks the column as allowing NULL values (NULL in SQL). Fields with Option<T> type are automatically treated as nullable, but this attribute can be used on non-Option types that should still allow NULL.#[model(sql_type = "SQL_TYPE_STRING")]: Specifies a custom SQL data type for the column. This overrides the default type mapping based on the Rust type. The string provided is used directly in the CREATE TABLE statement.#[model(skip)]: Excludes this field entirely from the generated SQLModel implementation. It will not be included in CREATE TABLE statements, INSERT/UPDATE queries, or deserialized by from_row. Useful for transient or computed fields.#[model(auto_increment)]: Applicable only to fields also marked with #[model(primary_key)] and having an integer type (like i32, i64, etc., often Option<i32>). Adds the database-specific syntax for auto-incrementing integer primary keys (SERIAL or GENERATED ALWAYS AS IDENTITY for PostgreSQL, AUTO_INCREMENT for MySQL, AUTOINCREMENT for SQLite).#[model(uuid)]: Applicable only to fields also marked with #[model(primary_key)] and having a uuid::Uuid or Option<uuid::Uuid> type. Adds database-specific default value generation for UUID primary keys (gen_random_uuid() for PostgreSQL, UUID() for MySQL, and a standard UUID generation expression for SQLite).The macro attempts to infer appropriate SQL data types for columns based on the Rust type of the field. This mapping is then translated to the specific syntax for the target database type in the CREATE TABLE statement.
| Rust Type | Mapped SqlType | Typical SQL Type Examples (PostgreSQL, MySQL, SQLite) |
|---|---|---|
i8, i16, i32, u8, u16, u32 |
Integer |
INTEGER, INT |
i64, u64 |
BigInt |
BIGINT |
f32, f64 |
Float |
REAL, DOUBLE PRECISION, FLOAT |
bool |
Boolean |
BOOLEAN, TINYINT(1) |
String, str |
Text |
TEXT, VARCHAR |
Uuid (from uuid crate`) |
Text |
TEXT, VARCHAR(36) (often stored as text) |
NaiveDate (from chrono crate) |
Date |
DATE |
NaiveTime (from chrono crate) |
Time |
TIME |
NaiveDateTime, DateTime (from chrono crate) |
DateTime |
TIMESTAMP, DATETIME |
Vec<u8> |
Blob |
BYTEA, BLOB |
Option<T> |
(Maps T) |
Adds NULL constraint |
serde_json::Value |
Blob |
BLOB (Consider using #[model(sql_type = "JSONB")] or similar for JSON types) |
You can always override this automatic mapping using the #[model(sql_type = "...") attribute on a field.
struct MyStruct { field1: Type, field2: Type, ... }). Tuple structs and unit structs are not supported.serde::Deserialize for the from_row method to function correctly, as row data is currently processed by converting it to a serde_json::Value object before deserialization.Uuid, NaiveDateTime, serde_json::Value) are included as dependencies in your Cargo.toml with necessary features (e.g., serde feature for integration).#[model(primary_key)]. The macro does not currently enforce this and may produce unexpected results if multiple fields are marked.primary_key_value method in the generated SQLModel currently returns Option<i32>, which is suitable for auto-increment integer primary keys. If you use Uuid or other types for your primary key, you might need to interact with the field directly or potentially extend the SQLModel trait in the main rusticx crate to support different primary key return types. Similarly, set_primary_key takes i32.