# Armature Macros Utils

Procedural utility macros for the Armature framework.

## Features

- ✅ **Response Builders** - Procedural macros for responses
- ✅ **Validation Helpers** - Compile-time validation macros
- ✅ **Model Derives** - Auto-implement common traits
- ✅ **Test Helpers** - Testing utility macros
- ✅ **Error Handling** - Bail and ensure macros

## Installation

```toml
[dependencies]
armature-macros-utils = { path = "../armature-macros-utils" }
```

## Procedural Macros

### Response Macros

```rust
use armature_macros_utils::{json, html, text, redirect};

// JSON response
json!({ "message": "Hello" })

// HTML response
html!("<h1>Welcome</h1>")

// Text response
text!("Hello, world!")

// Redirect
redirect!("/new-location")
```

### Validation Macros

```rust
use armature_macros_utils::{validate, validate_required, validate_email};

// Conditional validation
validate!(age >= 18, "Must be 18 or older");

// Required field validation
validate_required!(name);

// Email validation
validate_email!(user_email);
```

### Error Handling

```rust
use armature_macros_utils::{bail, ensure};

// Return early with error
if !found {
    bail!("User not found");
}

// Ensure condition or error
ensure!(user.is_active(), "User account is inactive");
```

### Model Derives

```rust
use armature_macros_utils::{Model, ApiModel, Resource};
use serde::{Serialize, Deserialize};

// Basic model
#[derive(Model, Serialize, Deserialize)]
pub struct User {
    pub id: i64,
    pub name: String,
}

// API model with field visibility
#[derive(ApiModel, Serialize, Deserialize)]
pub struct UserResponse {
    pub id: i64,
    pub name: String,
    #[api(skip)]
    pub password_hash: String,  // Excluded from API
}

// Resource model for database
#[derive(Resource, Serialize, Deserialize)]
#[resource(table = "users")]
pub struct UserEntity {
    #[resource(primary_key)]
    pub id: i64,
    pub name: String,
}
```

### Test Helpers

```rust
use armature_macros_utils::{test_request, assert_json, assert_status};

#[tokio::test]
async fn test_endpoint() {
    let req = test_request!(GET "/users/1");
    let resp = handler(req).await.unwrap();

    assert_status!(resp, 200);
    assert_json!(resp, { "id": 1, "name": "Alice" });
}
```

## Use with armature-macros

These crates work together:

```rust
// Declarative macros
use armature_macros::prelude::*;

// Procedural macros
use armature_macros_utils::*;

#[get("/users/:id")]
async fn get_user(req: HttpRequest) -> Result<HttpResponse, Error> {
    let id: i64 = path_param!(req, "id")?;  // From armature-macros

    match db.find(id).await {
        Some(user) => ok_json!(user),  // From armature-macros
        None => not_found!("User not found"),  // From armature-macros
    }
}
```

## Documentation

See the [Macros Guide](../../docs/guides/macros-guide.md) for comprehensive documentation.

## License

MIT OR Apache-2.0

