rok-utils 0.2.3

Laravel/AdonisJS-inspired utility helpers for the Rok ecosystem
Documentation
# Error Handling (`errors`)

AdonisJS-inspired typed error system with HTTP status semantics.

## Features

- **Typed errors**: `RokError` enum with machine-readable codes
- **Result extensions**: `ResultExt` trait for ergonomic error handling
- **HTTP status mapping**: Automatic HTTP status codes from error variants
- **Context wrapping**: Add context to any error source

## Error Codes

| Code | Status | Description |
|------|--------|-------------|
| `E_NOT_FOUND` | 404 | Resource not found |
| `E_UNAUTHORIZED` | 401 | Authentication required |
| `E_FORBIDDEN` | 403 | Access denied |
| `E_VALIDATION_FAILURE` | 422 | Input validation failed |
| `E_TOO_MANY_REQUESTS` | 429 | Rate limit exceeded |
| `E_INTERNAL` | 500 | Internal server error |
| `E_INVALID_JSON` | 500 | JSON parse failed |
| `E_INVALID_UUID` | 500 | Invalid UUID format |
| `E_INVALID_DATE` | 500 | Invalid date format |
| `E_WRAPPED` | 500 | Wrapped error with context |

## Quick Start

```rust
use rok_utils::{RokError, RokResultExt};

fn find_user(id: u64) -> Result<User, RokError> {
    db::find(id)
        .context("Failed to query user table")
        .or_not_found(&format!("User #{id}"))
}
```

## Error Creation

```rust
use rok_utils::RokError;

let err = RokError::NotFound("User #42".into());
assert_eq!(err.code(), "E_NOT_FOUND");
assert_eq!(err.status(), 404);
assert!(err.is_self_handled());
```

## Validation Errors

```rust
use rok_utils::RokError;

fn validate_email(email: &str) -> Result<(), RokError> {
    if email.contains('@') {
        Ok(())
    } else {
        Err(RokError::ValidationFailure {
            field: "email".to_string(),
            reason: "Must contain @".to_string(),
        })
    }
}
```

## Contextual Errors

```rust
use rok_utils::{RokResultExt, RokError};

let result = std::fs::read_to_string("config.toml")
    .context("Failed to read config file")
    .map_err(|e| RokError::Wrapped {
        message: "Configuration error".to_string(),
        source: Box::new(e),
    });
```

## See Also

- [Main examples]../docs/examples.md
- [Migration guide]../docs/migration-0x-to-1.0.md