rustlavel-validation 0.2.2

Rustlavel validation: Laravel-style rules with 422 JSON error responses
Documentation

rustlavel-validation: Laravel-style validation, written from scratch.

Rules are declared the way they are in Laravel — as a string — or built with methods when the compiler should check them:

# use rustlavel_validation::{validate, Rule, Validator};
# use rustlavel_http::Request;
# async fn example(request: &mut Request) {
let data = validate(request, &[("email", "required|email"), ("age", "integer|min:18")])
    .await
    .unwrap();

// the same rules, checked at compile time
let same = Validator::from_request(request)
    .rule("email", Rule::required().email())
    .rule("age", Rule::integer().min(18))
    .validate();
# let _ = (data, same);
# }

A failure is an [Errors] — field to messages — which turns into Laravel's 422 body, {"message": "...", "errors": {"email": ["..."]}}, for a client that wants JSON, and a plain 422 for a browser.

Why the entry point is async

Nothing here awaits yet. It is async because the rules that come next — Laravel's unique and exists — must ask the database, and this project treats a stable API as a feature. Better one .await today than a breaking signature change the week rustlavel-db lands.

Using ? in a handler

[Errors] implements [IntoResponse], so a handler can hand one straight back. Rust's orphan rules stop this crate from also implementing that trait for Result<_, Errors>Result belongs to core and the trait belongs to rustlavel-http — so [attempt] bridges the gap and lets the body of a handler use ? as normal:

# use rustlavel_validation::{attempt, validate};
# use rustlavel_http::{IntoResponse, Request, Response};
async fn store(mut request: Request) -> impl IntoResponse {
    attempt(async move {
        let data = validate(&mut request, &[("email", "required|email")]).await?;
        Ok(Response::json(data.into_json()))
    })
    .await
}