| Crates.io | domainstack-derive |
| lib.rs | domainstack-derive |
| version | 1.1.1 |
| created_at | 2026-01-06 13:49:59.63143+00 |
| updated_at | 2026-01-07 23:36:28.518106+00 |
| description | Derive macros for domainstack: #[derive(Validate, ToSchema, ToJsonSchema)] - validation + auto-generate OpenAPI/JSON Schema |
| homepage | |
| repository | https://github.com/blackwell-systems/domainstack |
| max_upload_size | |
| id | 2025894 |
| size | 189,855 |
Derive macros for the domainstack full-stack validation ecosystem.
Provides two derive macros that share the same unified rich syntax:
#[derive(Validate)] - Runtime validation#[derive(ToSchema)] - OpenAPI schema generationAdd this to your Cargo.toml:
[dependencies]
domainstack = { version = "1.0", features = ["derive"] } # Includes Validate
domainstack-derive = "1.0" # Adds ToSchema derive
domainstack-schema = "1.0" # Schema builder utilities
use domainstack::Validate;
#[derive(Validate)]
struct User {
#[validate(email)]
#[validate(max_len = 255)]
email: String,
#[validate(range(min = 18, max = 120))]
age: u8,
#[validate(min_len = 3)]
#[validate(max_len = 50)]
name: String,
}
NEW: Write validation rules ONCE, get BOTH runtime validation AND OpenAPI schemas:
use domainstack_derive::{Validate, ToSchema};
#[derive(Validate, ToSchema)]
struct User {
#[validate(email)] // [ok] Works for both validation and schema
#[validate(max_len = 255)]
#[schema(description = "User's email", example = "alice@example.com")]
email: String,
#[validate(range(min = 18, max = 120))]
#[schema(description = "User's age")]
age: u8,
#[validate(min_len = 3)]
#[validate(max_len = 50)]
name: String,
}
// Runtime validation works
user.validate()?;
// Schema generation works
let schema = User::schema();
// → email: { type: "string", format: "email", maxLength: 255, ... }
// → age: { type: "integer", minimum: 18, maximum: 120 }
Both Validate and ToSchema support these validation rules:
String Rules:
#[validate(email)] - Email format#[validate(url)] - URL format#[validate(min_len = n)] - Minimum length#[validate(max_len = n)] - Maximum length#[validate(alphanumeric)] - Alphanumeric only#[validate(ascii)] - ASCII only#[validate(alpha_only)] - Letters only#[validate(numeric_string)] - Digits only#[validate(non_empty)] - Not empty#[validate(non_blank)] - Not blank (no whitespace)#[validate(matches_regex = "pattern")] - Custom regexcontains, starts_with, ends_with, no_whitespaceNumeric Rules:
#[validate(range(min = a, max = b))] - Range validation#[validate(positive)] - Positive numbers#[validate(negative)] - Negative numbers#[validate(non_zero)] - Not zero#[validate(multiple_of = n)] - Multiple of nmin, max, finite, equals, not_equalsCollection Rules:
#[validate(min_items = n)] - Minimum items#[validate(max_items = n)] - Maximum items#[validate(unique)] - All items uniqueComposite Rules:
#[validate(nested)] - Validate nested struct#[validate(each(nested))] - Validate each item in collection (for nested types)#[validate(each(rule))] - Validate each item with any rule (for primitives)#[validate(custom = "function")] - Custom validation functionCollection Item Validation:
The each(rule) syntax allows validating each item in a collection:
#[derive(Validate)]
struct BlogPost {
// Validate each email in the list
#[validate(each(email))]
author_emails: Vec<String>,
// Validate each tag length
#[validate(each(length(min = 1, max = 50)))]
tags: Vec<String>,
// Validate each URL
#[validate(each(url))]
related_links: Vec<String>,
// Validate each item is alphanumeric
#[validate(each(alphanumeric))]
keywords: Vec<String>,
}
Error paths include array indices: tags[0], author_emails[1], etc.
Legacy Syntax (Still Supported):
#[validate(length(min = a, max = b))] - String length (prefer min_len/max_len)For ToSchema, add documentation metadata:
#[schema(description = "Field description")]
#[schema(example = "example value")]
#[schema(deprecated = true)]
#[schema(read_only = true)]
#[schema(write_only = true)]
#[derive(Validate)]
#[validate(
check = "self.password == self.password_confirmation",
code = "passwords_mismatch",
message = "Passwords must match"
)]
struct RegisterForm {
#[validate(min_len = 8)]
password: String,
password_confirmation: String,
}
This is a proc macro implementation crate. For complete documentation, examples, and usage guides, see:
Apache 2.0