UI frameworks
Validate Tauri command arguments, events, state and channel messages, without a tauri dependency.

vld-tauri validates JSON crossing the Tauri IPC boundary and returns a serializable error the frontend can read. It has no tauri dependency: add tauri to your app separately.

Install

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

No features. MSRV: 1.85 (see MSRV).

Example

use vld_tauri::prelude::*;

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

// Explicit validation: the frontend receives `VldTauriError` as JSON.
#[tauri::command]
fn create_user(payload: serde_json::Value) -> Result<String, VldTauriError> {
    let user = validate::<CreateUser>(payload)?;
    Ok(format!("Created {}", user.name))
}

// Validation during deserialization of the argument.
#[tauri::command]
fn create_user_auto(payload: VldPayload<CreateUser>) -> Result<String, VldTauriError> {
    Ok(format!("Created {}", payload.name))
}

The error serializes as:

{
  "error": "Validation failed",
  "issues": [{ "path": "name", "message": "String must be at least 2 characters" }]
}
import { invoke } from '@tauri-apps/api/core'

try {
  await invoke('create_user', { payload: { name: 'A', email: 'x' } })
} catch (err) {
  for (const issue of (err as { issues: { path: string; message: string }[] }).issues) {
    console.error(`${issue.path}: ${issue.message}`)
  }
}

API

  • validate::<T>(value) — validate a serde_json::Value; use it for commands, events, state, plugin config and channel messages.
  • validate_args::<T>(json_str) — parse a JSON string, then validate ("Invalid JSON" error on a parse failure).
  • VldPayload<T> — Deserialize wrapper that validates; Deref to T. VldEvent<T> is a type alias of it.
  • VldTauriError { error, issues: Vec<TauriIssue> } — from_vld, json_parse_error, custom, has_issues, issue_count.
  • TauriIssue { path, message }.

Gotchas

  • Issue paths have no leading dot: name, user.email, items[0].
  • With VldPayload<T> a validation failure surfaces as Tauri's argument deserialization error (a string "Validation failed: name: ...; email: ..."), not as VldTauriError. Take serde_json::Value and call validate when the frontend needs structured issues.
  • VldEvent<T> is VldPayload<T>: construct and match it as VldPayload(x).