Web frameworks
Salvo 1.x extractors that validate request data with vld schemas.

Extractors for Salvo 1.x. Each implements Salvo's Extractible, so it is a plain #[handler] parameter. Shared rules (status codes, error body, coercion, headers and cookies) are on the web adapters overview.

Install

Cargo.toml
[dependencies]
vld = "0.5"
vld-salvo = "0.5"
salvo = "1"

No features. The crate enables salvo's server, http1 and cookie features. MSRV 1.94 (Salvo 1.x), see MSRV.

Example

use salvo::prelude::*;
use vld_salvo::prelude::*;

vld::schema! {
    #[derive(Debug, Clone)]
    pub struct CreateUser {
        pub name: String  => vld::string().min(2).max(50),
        pub email: String => vld::string().email(),
    }
}

vld::schema! {
    #[derive(Debug, Clone)]
    pub struct UserIdPath {
        pub id: i64 => vld::number().int().min(1),
    }
}

#[handler]
async fn create_user(body: VldJson<CreateUser>, res: &mut Response) {
    res.render(Json(serde_json::json!({ "name": body.name })));
}

#[handler]
async fn get_user(p: VldPath<UserIdPath>, res: &mut Response) {
    res.render(format!("user #{}", p.id));
}

#[tokio::main]
async fn main() {
    let router = Router::new()
        .push(Router::with_path("users").post(create_user))
        .push(Router::with_path("users/{id}").get(get_user));

    let acceptor = TcpListener::new("0.0.0.0:5800").bind().await;
    Server::new(acceptor).serve(router).await;
}

API

ItemPurpose
VldJson<T>JSON body; 415 without a JSON Content-Type (also accepts application/*+json, unlike Salvo's parse_json)
VldQuery<T>Query string, coerced
VldForm<T>application/x-www-form-urlencoded body
VldPath<T>Route parameters (users/{id}), coerced
VldHeaders<T>Request headers
VldCookie<T>Cookies from every Cookie header
VldSalvoErrorRejection written as JSON (Writer); status(), body(), error(); From<VldError>
preludeAll of the above plus vld::prelude::*

All extractors deref to T. VldSalvoError also works as the error type of a handler returning Result<_, VldSalvoError>.

Body limit

Bodies are read up to Salvo's secure_max_size, set with the SecureMaxSize middleware, Request::set_secure_max_size or salvo::http::request::set_global_secure_max_size:

use salvo::http::request::SecureMaxSize;

let router = Router::new()
    .hoop(SecureMaxSize::new(1024 * 1024))
    .push(Router::with_path("users").post(create_user));

Gotchas

  • While secure_max_size is Salvo's built-in 64 KiB default, vld uses its own 2 MiB default instead, like every other adapter. Setting exactly 64 KiB therefore counts as "unset"; use any other value to lower the limit.
  • Over-limit bodies are 413 with the JSON body {"error": "Payload too large"}, for forms too.
  • Salvo 1.x only. A version range across majors would load two salvo_core copies and break Extractible.