Crate domainstack_derive

Crate domainstack_derive 

Source
Expand description

§domainstack-derive

Derive macros for domainstack validation and schema generation.

§Provided Macros

  • #[derive(Validate)] - Automatic validation implementation with #[validate(...)] attributes
  • #[derive(ToSchema)] - OpenAPI 3.0 schema generation from validation rules
  • #[derive(ToJsonSchema)] - JSON Schema (Draft 2020-12) generation from validation rules
  • #[derive(ValidateOnDeserialize)] - Validate automatically during serde deserialization (requires serde feature)

§#[derive(Validate)]

Generates a Validate trait implementation that validates all fields with #[validate(...)] attributes.

§Structs with Named Fields

use domainstack::prelude::*;
use domainstack_derive::Validate;

#[derive(Debug, Validate)]
struct User {
    #[validate(length(min = 2, max = 50))]
    name: String,

    #[validate(range(min = 18, max = 120))]
    age: u8,
}

let user = User { name: "Alice".to_string(), age: 30 };
assert!(user.validate().is_ok());

§Tuple Structs (Newtypes)

Perfect for type-safe wrappers with validation:

use domainstack::prelude::*;
use domainstack_derive::Validate;

#[derive(Debug, Validate)]
struct Email(#[validate(email)] String);

#[derive(Debug, Validate)]
struct Age(#[validate(range(min = 0, max = 150))] u8);

let email = Email("user@example.com".to_string());
assert!(email.validate().is_ok());

let age = Age(25);
assert!(age.validate().is_ok());

§Enums

Supports unit, tuple, and struct variants:

use domainstack::prelude::*;
use domainstack_derive::Validate;

#[derive(Debug, Validate)]
enum PaymentMethod {
    // Unit variant - always valid
    Cash,

    // Tuple variant
    Card(#[validate(length(min = 13, max = 19))] String),

    // Struct variant
    BankTransfer {
        #[validate(alphanumeric)]
        account: String,
        #[validate(length(min = 6, max = 11))]
        routing: String,
    },
}

let cash = PaymentMethod::Cash;
assert!(cash.validate().is_ok());

let card = PaymentMethod::Card("4111111111111111".to_string());
assert!(card.validate().is_ok());

§#[derive(ToSchema)]

Generates a ToSchema trait implementation that produces OpenAPI 3.0 schemas from validation rules.

use domainstack_derive::{Validate, ToSchema};

#[derive(Validate, ToSchema)]
struct User {
    #[validate(email)]
    #[validate(max_len = 255)]
    email: String,

    #[validate(range(min = 18, max = 120))]
    age: u8,
}

let schema = User::schema();
// → email: { type: "string", format: "email", maxLength: 255 }
// → age: { type: "integer", minimum: 18, maximum: 120 }

§#[derive(ToJsonSchema)]

Generates a ToJsonSchema trait implementation that produces JSON Schema (Draft 2020-12) from validation rules. Requires the schema feature.

use domainstack_derive::{Validate, ToJsonSchema};

#[derive(Validate, ToJsonSchema)]
struct User {
    #[validate(email)]
    #[validate(max_len = 255)]
    email: String,

    #[validate(range(min = 18, max = 120))]
    age: u8,
}

let schema = User::json_schema();
// → email: { type: "string", format: "email", maxLength: 255 }
// → age: { type: "integer", minimum: 18, maximum: 120 }

§#[derive(ValidateOnDeserialize)]

Validates during serde deserialization, returning validation errors instead of serde errors.

use domainstack_derive::ValidateOnDeserialize;

#[derive(ValidateOnDeserialize)]
struct User {
    #[validate(email)]
    email: String,

    #[validate(range(min = 18, max = 120))]
    age: u8,
}

// Validation happens automatically during deserialization
let user: User = serde_json::from_str(r#"{"email": "alice@example.com", "age": 30}"#)?;
// ↑ If this succeeds, user is guaranteed valid!

Derive Macros§

ToSchema
Validate