UI frameworks
Shared validation for Dioxus server functions and WASM clients, without a dioxus dependency.

vld-dioxus lets the same vld schemas check server-function arguments on the server and form fields in the browser. It has no dioxus dependency (it works with any Dioxus version) and builds for native and WASM targets.

Install

Cargo.toml
[dependencies]
vld = "0.5"
vld-dioxus = "0.5"

No features. MSRV: 1.85 (see MSRV).

Example

use dioxus::prelude::*;

// Shared rules, compiled for the server and the client.
fn name_schema() -> vld::primitives::ZString { vld::string().min(2).max(50) }
fn email_schema() -> vld::primitives::ZString { vld::string().email() }

#[server]
async fn create_user(name: String, email: String) -> Result<(), ServerFnError> {
    vld_dioxus::validate_args! {
        name  => name_schema(),
        email => email_schema(),
    }
    .map_err(|e| ServerFnError::new(e.to_string()))?;
    Ok(())
}

#[component]
fn CreateUserForm() -> Element {
    let name = use_signal(String::new);
    let name_error = use_memo(move || vld_dioxus::check_field(&name(), &name_schema()));
    // ... render the input and `name_error`
    rsx! {}
}

On the client, recover the field errors from the server-function error:

if let Some(err) = vld_dioxus::VldServerError::from_server_message(&e.to_string()) {
    let name_msg = err.field_error("name");
}

API

  • validate_args! { arg => schema, ... } — validate local values; Result<(), VldServerError> with one FieldError per issue (field = argument name, nested issues as arg.sub / arg[0]).
  • validate::<S, T>(&value) / validate_value::<S>(&json) — validate against a schema type.
  • check_field(&value, &schema) — first error message or None; check_field_all — all messages.
  • check_all_fields::<S, T>(&value) — Vec<FieldError> for a whole form.
  • VldServerError { message, fields } — validation, internal, field_error, field_errors, has_field_error, error_fields, from_json, from_server_message; Display is its JSON.
  • FieldError { field, message }.
  • prelude — all of the above plus vld::prelude::*.

Gotchas

  • Field paths have no leading dot: name, user.email, items[0].
  • ServerFnError's Display adds a prefix before the JSON, so from_json(&e.to_string()) does not match; use from_server_message, which reads from the first { to the last }.
  • A value that fails to serialize is reported as an error, never as valid.