Expand description
§vld-tauri — Tauri validation for vld
Provides helpers for validating Tauri IPC commands,
events, state, plugin config and channel messages using vld schemas.
This crate does not depend on tauri itself — it only needs vld,
serde and serde_json, keeping the dependency tree minimal.
You add tauri as a separate dependency in your app.
§Overview
| Item | Use case |
|---|---|
validate | General-purpose JSON validation |
validate_args | Validate a raw JSON string |
validate_event | Validate incoming event payloads |
validate_state | Validate app state / config at init |
validate_channel_message | Validate outgoing channel messages |
validate_plugin_config | Validate plugin JSON config |
VldTauriError | Serializable error for #[tauri::command] results |
VldPayload<T> | Auto-validating Deserialize wrapper |
VldEvent<T> | Auto-validating Deserialize wrapper for events |
§Usage patterns
§IPC commands — explicit validation (recommended)
Accept serde_json::Value and validate manually.
The frontend receives structured error JSON on failure.
ⓘ
use vld_tauri::prelude::*;
vld::schema! {
#[derive(Debug, Clone, serde::Serialize)]
pub struct CreateUser {
pub name: String => vld::string().min(2).max(50),
pub email: String => vld::string().email(),
}
}
#[tauri::command]
fn create_user(payload: serde_json::Value) -> Result<String, VldTauriError> {
let user = validate::<CreateUser>(payload)?;
Ok(format!("Created {}", user.name))
}§IPC commands — auto-validated payload
VldPayload<T> implements Deserialize and validates during
deserialization. If validation fails, Tauri reports a deserialization
error with the full validation message.
ⓘ
#[tauri::command]
fn create_user(payload: VldPayload<CreateUser>) -> Result<String, VldTauriError> {
Ok(format!("Created {}", payload.name))
}§Event payloads
Validate data from emit()/listen():
ⓘ
use tauri::{Emitter, Listener};
// Backend: validate incoming event from frontend
app.listen("user:update", |event| {
let payload: serde_json::Value = serde_json::from_str(event.payload()).unwrap();
match validate_event::<UserUpdate>(payload) {
Ok(update) => println!("Valid update: {:?}", update),
Err(e) => eprintln!("Bad event: {e}"),
}
});
// Or auto-validate with VldEvent<T>:
let event: VldEvent<UserUpdate> = serde_json::from_str(event.payload()).unwrap();§State validation at init
ⓘ
let config_json = std::fs::read_to_string("config.json").unwrap();
let config = validate_state::<AppConfig>(
serde_json::from_str(&config_json).unwrap()
).expect("Invalid app config");
app.manage(config);§Plugin config validation
ⓘ
let plugin_cfg: serde_json::Value = /* from tauri.conf.json */;
let cfg = validate_plugin_config::<MyPluginConfig>(plugin_cfg)
.expect("Invalid plugin config");§Channel message validation
ⓘ
#[tauri::command]
fn stream(channel: Channel<serde_json::Value>) -> Result<(), VldTauriError> {
let msg = ProgressUpdate { percent: 50, status: "working".into() };
let validated = validate_channel_message::<ProgressUpdate>(
serde_json::to_value(&msg).unwrap()
)?;
channel.send(serde_json::to_value(&validated).unwrap()).unwrap();
Ok(())
}§Frontend usage (TypeScript)
import { invoke } from '@tauri-apps/api/core';
interface VldError {
error: string;
issues: Array<{ path: string; message: string }>;
}
try {
const result = await invoke('create_user', {
payload: { name: 'Alice', email: 'alice@example.com' }
});
} catch (err) {
const vldErr = err as VldError;
for (const issue of vldErr.issues) {
console.error(`${issue.path}: ${issue.message}`);
}
}Modules§
- prelude
- Prelude — import everything you need.
Structs§
- Tauri
Issue - Single validation issue, serialised for the frontend.
- VldEvent
- Auto-validating wrapper for Tauri event payloads.
- VldPayload
- Auto-validating wrapper for Tauri command parameters.
- VldTauri
Error - Serializable error type for Tauri IPC commands, events, and channel messages.
Functions§
- validate
- Validate a
serde_json::Valueagainst avldschema. - validate_
args - Validate a raw JSON string against a
vldschema. - validate_
channel_ message - Validate an outgoing channel message before sending it to the
frontend via
Channel::send(). - validate_
event - Validate an event payload received from the frontend via
Emitter::emit()/Listener::listen(). - validate_
plugin_ config - Validate a Tauri plugin configuration (usually from
tauri.conf.json). - validate_
state - Validate app state / configuration before calling
app.manage().