vld
Type-safe runtime validation for Rust, inspired by Zod.
vld combines schema definition with type-safe parsing. Define your validation
rules once and get both runtime checks and strongly-typed Rust structs.
Features
- Zero-cost schema definitions — the
schema!macro generates plain Rust structs with built-inparse()methods. Or useschema_validated!to get lenient parsing too. - Error accumulation — all validation errors are collected, not just the first one.
- Rich primitives — string, number, integer, boolean, literal, enum, any, custom.
- String formats — email, URL, UUID, IPv4, IPv6, Base64, ISO date/time/datetime, hostname, CUID2, ULID, Nano ID, emoji.
All validated without regex by default. Every check has a
_msgvariant for custom messages. - Composable — optional, nullable, nullish, default, catch, refine, super_refine, transform, pipe, preprocess, describe,
.or(),.and(). - Collections — arrays, tuples (up to 6), records, Map (
HashMap), Set (HashSet). - Unions —
union(a, b),union3(a, b, c),.or(),discriminated_union("field"),intersection(a, b),.and(). - Recursive schemas —
lazy()for self-referencing data structures (trees, graphs). - Dynamic objects —
strict(),strip(),passthrough(),pick(),omit(),extend(),merge(),partial(),required(),catchall(),keyof(). - Custom schemas —
vld::custom(|v| ...)for arbitrary validation logic. - Multiple input sources — parse from
&str,String,&[u8],Path,PathBuf, orserde_json::Value. - Validate existing values —
.validate(&value)and.is_valid(&value)work with anySerializetype.schema!structs getStruct::validate(&instance). - Lenient parsing —
parse_lenient()returnsParseResult<T>with the struct, per-field diagnostics, and.save_to_file(). - Error formatting —
prettify_error,flatten_error,treeify_errorutilities. - Custom error messages —
_msgvariants,type_error(), andwith_messages()for per-check and bulk message overrides, including translations. - JSON Schema / OpenAPI —
JsonSchematrait on all schema types;json_schema()andto_openapi_document()onschema!structs;field_schema()for rich object property schemas;to_openapi_document_multi()helper. - Derive macro —
#[derive(Validate)]with#[vld(...)]attributes (optionalderivefeature). - Benchmarks — criterion-based benchmarks included.
- CI — GitHub Actions workflow for testing, clippy, and formatting.
- Minimal dependencies — only
serdeandserde_json. Regex and derive macro are optional features.
Quick Start
Add to your Cargo.toml:
[]
= "0.1"
Optional Features
All features are disabled by default:
| Feature | Description |
|---|---|
serialize |
Adds #[derive(Serialize)] on error/result types, enables VldSchema::validate()/is_valid(), ParseResult::save_to_file()/to_json_string()/to_json_value() |
deserialize |
Adds #[derive(Deserialize)] on error/result types |
openapi |
Enables JsonSchema trait, to_json_schema(), json_schema(), to_openapi_document(), field_schema() |
diff |
Schema diffing — compare two JSON Schemas to detect breaking vs non-breaking changes |
regex |
Custom regex patterns via .regex() (uses regex-lite) |
derive |
#[derive(Validate)] procedural macro |
chrono |
ZDate / ZDateTime types with chrono parsing |
Enable features as needed:
[]
= { = "0.1", = ["serialize", "openapi"] }
Basic Usage
use *;
// Define a validated struct
schema!
// Parse from a JSON string
let user = parse.unwrap;
assert_eq!;
assert_eq!;
// Errors are accumulated
let err = parse.unwrap_err;
assert!;
Nested Structs
use *;
schema!
schema!
let user = parse.unwrap;
Primitives
String
string
.min // minimum length
.max // maximum length
.len // exact length
.email // email format
.url // URL format (http/https)
.uuid // UUID format
.ipv4 // IPv4 address
.ipv6 // IPv6 address
.base64 // Base64 string
.iso_date // ISO 8601 date (YYYY-MM-DD)
.iso_time // ISO 8601 time (HH:MM:SS)
.iso_datetime // ISO 8601 datetime
.hostname // valid hostname
.cuid2 // CUID2 format
.ulid // ULID format (26 chars, Crockford Base32)
.nanoid // Nano ID format (alphanumeric + _-)
.emoji // must contain emoji
.starts_with // must start with
.ends_with // must end with
.contains // must contain
.non_empty // must not be empty
.trim // trim whitespace before validation
.to_lowercase // convert to lowercase
.to_uppercase // convert to uppercase
.coerce // coerce numbers/booleans to string
Number
number
.min // minimum (inclusive)
.max // maximum (inclusive)
.gt // greater than (exclusive)
.lt // less than (exclusive)
.positive // > 0
.negative // < 0
.non_negative // >= 0
.finite // not NaN or infinity
.multiple_of
.safe // JS safe integer range (-(2^53-1) to 2^53-1)
.int // switch to integer mode (i64)
.coerce // coerce strings/booleans to number
Integer
number.int
.min
.max
.gte
.positive
Boolean
boolean
.coerce // "true"/"false"/"1"/"0" -> bool
Literal
literal // exact string match
literal // exact integer match
literal // exact boolean match
Enum
enumeration
Any
any // accepts any JSON value
Modifiers
// Optional: null/missing -> None
string.optional
// Nullable: null -> None
string.nullable
// Nullish: both optional + nullable
string.nullish
// Default: null/missing -> default value
string.with_default
// Catch: ANY error -> fallback value
string.min.catch
Collections
Array
array
.min_len
.max_len
.len // exact length
.non_empty // alias for min_len(1)
Tuple
// Tuples of 1-6 elements
let schema = ;
let = schema.parse.unwrap;
Record
record
.min_keys
.max_keys
Map
// Input: [["a", 1], ["b", 2]] -> HashMap
map
Set
// Input: ["a", "b", "a"] -> HashSet {"a", "b"}
set
.min_size
.max_size
Combinators
Union
// Union of 2 types
let schema = union;
// Returns Either<String, i64>
// Union of 3 types
let schema = union3;
// Returns Either3<String, f64, bool>
union! macro
For convenience, use the union! macro to combine 2–6 schemas without
nesting calls manually. The macro dispatches to union() / union3() or
nests them automatically for higher arities:
use *;
// 2 schemas — same as vld::union(a, b)
let s2 = union!;
// 3 schemas — same as vld::union3(a, b, c)
let s3 = union!;
// 4 schemas — nested automatically
let s4 = union!;
// 5 and 6 schemas work the same way
let s5 = union!;
You can also use the method chaining equivalent .or() for two schemas:
let schema = string.or;
Discriminated Union
// Efficient union by discriminator field
let schema = discriminated_union
.variant_str
.variant_str;
Intersection
// Input must satisfy both schemas
let schema = intersection;
Refine
number.int.refine
Super Refine
// Produce multiple errors in one check
string.super_refine
Transform
string.transform // String -> usize
Pipe
// Chain schemas: output of first -> input of second
string
.transform
.pipe
Preprocess
preprocess
Lazy (Recursive)
// Self-referencing schemas for trees, graphs, etc.
Describe
// Attach metadata (does not affect validation)
string.min.describe
Dynamic Object
For runtime-defined schemas (without compile-time type safety):
let obj = object
.field
.field
.strict; // reject unknown fields
// .strip() // remove unknown fields (default)
// .passthrough() // keep unknown fields as-is
// Object manipulation
let base = object.field.field;
base.pick // keep only "a"
base.omit // remove "b"
base.partial // all fields become optional
base.required // all fields must not be null (opposite of partial)
base.deep_partial // partial (nested objects: apply separately)
base.extend // merge fields from another schema
base.merge // alias for extend
base.catchall // validate unknown fields with a schema
base.keyof // Vec<String> of field names
Per-Field Validation & Lenient Parsing
Use schema_validated! for zero-duplication, or schema! + impl_validate_fields! separately:
use *;
// Option A: single macro (requires Serialize + Default on field types)
schema_validated!
// Option B: separate macros (more control)
// vld::schema! { ... }
// vld::impl_validate_fields!(User { name: String => ..., });
validate_fields — per-field diagnostics
let results = validate_fields.unwrap;
for f in &results
// Output:
// ✖ name: String must be at least 2 characters (received: "X")
// ✖ email: Invalid email address (received: "bad")
// ✔ age: null
parse_lenient — returns a ParseResult<T>
parse_lenient returns a [ParseResult<T>] — a wrapper around the struct and
per-field diagnostics. You can inspect it, convert to JSON, or save to a file
whenever you want.
let result = parse_lenient.unwrap;
// Inspect
println!; // false
println!; // 2
println!; // User { name: "", email: "", age: None }
// Per-field diagnostics
for f in result.fields
// Only errors
for f in result.error_fields
// Display trait prints a summary
println!;
// Convert to JSON string
let json = result.to_json_string.unwrap;
// Save to file at any time
result.save_to_file.unwrap;
// Or extract the struct
let user = result.into_value;
ParseResult<T> methods:
| Method | Description |
|---|---|
.value |
The constructed struct (invalid fields use Default) |
.fields() |
All per-field results (&[FieldResult]) |
.valid_fields() |
Only passed fields |
.error_fields() |
Only failed fields |
.is_valid() |
true if all fields passed |
.has_errors() |
true if any field failed |
.valid_count() |
Number of valid fields |
.error_count() |
Number of invalid fields |
.save_to_file(path) |
Serialize to JSON file (requires Serialize) |
.to_json_string() |
Serialize to JSON string |
.to_json_value() |
Serialize to serde_json::Value |
.into_value() |
Consume and return the inner struct |
.into_parts() |
Consume and return (T, Vec<FieldResult>) |
Single-Field Extraction
Parse the entire schema first, then extract individual fields from the result.
Use parse_lenient + .field("name") to inspect a specific field's validation
status — even when other fields are invalid:
use *;
// Define and register per-field validation
schema!
impl_validate_fields!;
// Strict parse — access fields directly
let user = parse.unwrap;
println!; // "Alex"
// Lenient parse — some fields may be invalid
let result = parse_lenient.unwrap;
// The struct is always available (invalid fields use Default)
println!; // 25 — valid, kept as-is
// Check a specific field
let name_field = result.field.unwrap;
println!; // ✖ name: String must be at least 2 characters
println!; // false
let age_field = result.field.unwrap;
println!; // ✔ age: 25
println!; // true
Error Formatting
use ;
match parse
Input Sources
Schemas accept any type implementing VldInput:
// JSON string
parse?;
// serde_json::Value
let val = json!;
parse?;
// File path
parse?;
// Byte slice
parse?;
Validate Existing Rust Values
Requires the
serializefeature.
Instead of only parsing JSON, you can validate any existing Rust value using
.validate() and .is_valid(). The value is serialized to JSON internally,
then validated against the schema.
On any schema
use *;
// Validate a Vec
let schema = array.min_len.max_len;
assert!;
assert!;
// Validate a String
let email = string.email;
assert!;
assert!;
// Validate a number
let age = number.int.min.max;
assert!;
assert!;
// Validate a HashMap
let schema = record;
let mut map = new;
map.insert;
assert!;
On schema! structs
Structs with #[derive(serde::Serialize)] get validate() and is_valid()
that check an already-constructed instance against the schema:
use *;
schema!
// Construct a struct normally (bypassing parse)
let user = User ;
// Validate it
assert!;
let err = validate.unwrap_err;
// err contains: .name: too short, .email: invalid
// Also works with serde_json::Value or any Serialize type
let json = json!;
assert!;
impl_rules! — Attach Validation to Existing Structs
Use impl_rules! to add .validate() and .is_valid() to a struct you
already have. No need to redefine it — just list the field rules:
use *;
// No #[derive(Serialize)] or #[derive(Debug)] required
impl_rules!;
let p = Product ;
assert!;
let bad = Product ;
assert!;
let err = bad.validate.unwrap_err;
for issue in &err.issues
// .name: String must be at least 2 characters
// .price: Number must be positive
// .quantity: Number must be non-negative
// .tags[0]: String must be at least 1 characters
The struct itself does not need Serialize or Debug — each field is
serialized individually (standard types like String, f64, Vec<T> already
implement Serialize). You can use all schema features inside impl_rules!:
with_messages(), type_error(), refine(), etc.
Chain Syntax: .or() / .and()
// Union via method chaining
let schema = string.or;
// Equivalent to vld::union(vld::string(), vld::number().int())
// Intersection via method chaining
let bounded = string.min.and;
// Input must satisfy both constraints
Custom Schema
Create a schema from any closure:
let even = custom;
assert_eq!;
assert!;
JSON Schema / OpenAPI Generation
Requires the
openapifeature.
Generate JSON Schema (compatible with OpenAPI 3.1)
from any vld schema via the JsonSchema trait:
use *; // imports JsonSchema trait
// Any individual schema
let js = string.min.max.email.json_schema;
// {"type": "string", "minLength": 2, "maxLength": 50, "format": "email"}
// Collections
let js = array.min_len.json_schema;
// {"type": "array", "items": {"type": "integer", ...}, "minItems": 1}
// Modifiers (optional wraps with oneOf)
let js = string.email.optional.json_schema;
// {"oneOf": [{"type": "string", "format": "email"}, {"type": "null"}]}
// Unions → oneOf, Intersections → allOf
let js = union.json_schema;
// {"oneOf": [{"type": "string"}, {"type": "number"}]}
Object field schemas
Use field_schema() (instead of field()) to include full JSON Schema for
each property:
let js = object
.field_schema
.field_schema
.strict
.json_schema;
// {"type": "object", "properties": {"email": {...}, "score": {...}}, ...}
schema! macro — struct-level JSON Schema
Structs defined via schema! automatically get json_schema() and
to_openapi_document() class methods:
use *;
schema!
// Full JSON Schema for the struct
let schema = json_schema;
// {
// "type": "object",
// "required": ["name", "email", "age"],
// "properties": {
// "name": {"type": "string", "minLength": 2, "maxLength": 100},
// "email": {"type": "string", "format": "email"},
// "age": {"type": "integer", "minimum": 0}
// }
// }
// Wrap in a minimal OpenAPI 3.1 document
let doc = to_openapi_document;
// {"openapi": "3.1.0", "components": {"schemas": {"User": {...}}}, ...}
Multi-schema OpenAPI document
use to_openapi_document_multi;
let doc = to_openapi_document_multi;
JsonSchema trait
The trait is implemented for all core types: ZString, ZNumber, ZInt,
ZBoolean, ZEnum, ZAny, ZArray, ZRecord, ZSet, ZObject,
ZOptional, ZNullable, ZNullish, ZDefault, ZCatch, ZRefine,
ZTransform, ZDescribe, ZUnion2, ZUnion3, ZIntersection,
NestedSchema.
Custom Error Messages
Error messages are configured at the schema level, not after validation. There are three mechanisms:
1. _msg variants — per-check custom messages
Every validation method has a _msg variant that accepts a custom error message:
use *;
let schema = string
.min_msg
.max_msg
.email_msg;
let err = schema.parse.unwrap_err;
// -> "Name must be at least 3 characters"
// -> "Please enter a valid email"
Available on all string checks (email_msg, url_msg, uuid_msg, ipv4_msg, etc.)
and number checks are set via with_messages (see below).
2. type_error() — custom type mismatch message
Override the "Expected X, received Y" message when the input has the wrong JSON type:
use *;
let schema = string.type_error;
let err = schema.parse.unwrap_err;
assert!;
let schema = number.type_error;
let schema = number.int.int_error;
3. with_messages() — bulk override by check key
Override multiple messages at once using check category keys. The closure receives
the key and returns Some(new_message) to replace, or None to keep the original:
use *;
let schema = string.min.max.email
.with_messages;
Works on numbers too — great for translations:
use *;
let schema = number.min.max
.with_messages;
For integers, the key "not_int" overrides the "not an integer" message:
use *;
let schema = number.int.min.max
.with_messages;
4. In objects — per-field custom messages
Combine type_error() and with_messages() on individual fields:
use *;
let schema = object
.field
.field;
String check keys
| Key | Check |
|---|---|
too_small |
min |
too_big |
max |
invalid_length |
len |
invalid_email |
email |
invalid_url |
url |
invalid_uuid |
uuid |
invalid_regex |
regex |
invalid_starts_with |
starts_with |
invalid_ends_with |
ends_with |
invalid_contains |
contains |
non_empty |
non_empty |
invalid_ipv4 |
ipv4 |
invalid_ipv6 |
ipv6 |
invalid_base64 |
base64 |
invalid_iso_date |
iso_date |
invalid_iso_datetime |
iso_datetime |
invalid_iso_time |
iso_time |
invalid_hostname |
hostname |
invalid_cuid2 |
cuid2 |
invalid_ulid |
ulid |
invalid_nanoid |
nanoid |
invalid_emoji |
emoji |
Number check keys
| Key | Check |
|---|---|
too_small |
min, gt, gte |
too_big |
max, lt, lte |
not_positive |
positive |
not_negative |
negative |
not_non_negative |
non_negative |
not_non_positive |
non_positive |
not_finite |
finite |
not_multiple_of |
multiple_of |
not_safe |
safe |
not_int |
int (ZInt only) |
Derive Macro
Enable the derive feature for #[derive(Validate)]:
[]
= { = "0.1", = ["derive"] }
use Validate;
// Generates: vld_parse(), parse_value(), validate_fields(), parse_lenient()
let user = vld_parse.unwrap;
Derive + utoipa (OpenAPI)
#[derive(Validate)] works with impl_to_schema! from vld-utoipa, including
full support for #[serde(rename_all = "...")]. Enable both derive and openapi features:
[]
= { = "0.1", = ["derive", "openapi"] }
= "0.1"
= "5"
use Validate;
use impl_to_schema;
impl_to_schema!;
// OpenAPI schema uses camelCase keys: "streetAddress", "streetNumber", etc.
// Validation also expects camelCase JSON input.
Optional Regex Support
Requires the
regexfeature.
By default, vld validates all string formats (email, UUID, etc.) without regex.
If you need custom regex patterns via .regex(), enable the regex feature:
[]
= { = "0.1", = ["regex"] }
let schema = string.regex;
Running the Playground
Benchmarks
Workspace Crates
The vld project is organized as a Cargo workspace with several crates:
| Crate | Version | Description |
|---|---|---|
vld |
Core validation library — schemas, parsers, macros, error handling, i18n | |
vld-derive |
Procedural macro #[derive(Validate)] for automatic struct validation |
|
vld-axum |
Axum — extractors VldJson, VldQuery, VldPath, VldForm, VldHeaders, VldCookie |
|
vld-actix |
Actix-web — extractors VldJson, VldQuery, VldPath, VldForm, VldHeaders, VldCookie |
|
vld-rocket |
Rocket — extractors VldJson, VldQuery, VldForm + JSON error catchers |
|
vld-poem |
Poem — extractors VldJson, VldQuery, VldForm, VldPath, VldHeaders, VldCookie |
|
vld-warp |
Warp — filters vld_json, vld_query, vld_param, vld_path + handle_rejection |
|
vld-salvo |
Salvo — extractors VldJson, VldQuery, VldPath, VldForm, VldHeaders, VldCookie |
|
vld-tower |
Universal Tower middleware — validate JSON bodies in any Tower-compatible framework | |
vld-diesel |
Diesel ORM — Validated<S, T> wrapper, VldText, VldInt column types |
|
vld-sea |
SeaORM — validate ActiveModel before insert/update |
|
vld-utoipa |
utoipa — auto-generate ToSchema from vld definitions |
|
vld-aide |
aide / schemars — auto-generate JsonSchema from vld definitions |
|
vld-config |
Config validation — TOML/YAML/JSON/ENV via config-rs or figment | |
vld-clap |
Clap — validate CLI arguments via #[derive(Validate)] |
|
vld-tauri |
Tauri — validate IPC commands, events, state, channels, plugin config | |
vld-ts |
TypeScript codegen — generates Zod schemas from vld JSON Schema output |
|
vld-fake |
Fake data generation — User::fake(), fake_many(), fake_seeded() with realistic dictionaries |
|
vld-sqlx |
SQLx — validate before insert/update, typed column wrappers | |
vld-tonic |
tonic gRPC — validate protobuf messages and metadata | |
vld-leptos |
Leptos — shared validation for server functions and WASM clients | |
vld-dioxus |
Dioxus — shared validation for server functions and WASM clients | |
vld-ntex |
ntex — extractors VldJson, VldQuery, VldPath, VldForm, VldHeaders, VldCookie |
|
vld-surrealdb |
SurrealDB — validate JSON documents before create/insert/update and after select | |
vld-schemars |
schemars — bidirectional bridge between vld and schemars JSON Schema | |
vld-http-common |
Shared HTTP helpers — query parsing, value coercion, error formatting (used by web crates) |
vld-derive
Enable with features = ["derive"]. Provides #[derive(Validate)] with #[vld(...)] attributes
on struct fields. Supports #[serde(rename)] and #[serde(rename_all)] for JSON key mapping.
When openapi feature is also enabled, generates json_schema() and to_openapi_document() methods,
making it fully compatible with vld-utoipa's impl_to_schema!.
use Validate;
vld-axum
Validation extractors for Axum web framework. Automatically validates request data
and returns 422 Unprocessable Entity with structured JSON errors on failure.
[]
= "0.1"
use *;
async
vld-actix
Validation extractors for Actix-web framework. Same API surface as vld-axum.
[]
= "0.1"
use *;
async
vld-ntex
Validation extractors for ntex web framework (by the author of Actix). Same API surface as vld-actix.
[]
= "0.1"
= "3"
use HttpResponse;
use *;
async
vld-diesel
Integration with Diesel ORM. Validate data before insert/update, validate rows after load,
and use validated column types (VldText<S>, VldInt<S>) that enforce constraints at the type level.
[]
= { = "0.1", = ["sqlite"] }
use *;
let validated = ?;
insert_into.values.execute?;
vld-tower
Universal Tower middleware for JSON body validation. Works with any Tower-compatible framework (Axum, Hyper, Tonic, Warp).
[]
= "0.1"
use ;
use ServiceBuilder;
schema!
// One layer covers all routes
let svc = new
.layer
.service_fn;
// In handler — zero-cost extraction from extensions
let user: CreateUser = validated;
vld-config
Validate configuration files at load time. Supports config-rs (TOML, YAML, JSON, ENV) and figment.
[]
= "0.1"
= "0.1" # config-rs by default
# vld-config = { version = "0.1", features = ["figment"] }
use *;
schema!
let config = builder
.add_source
.add_source
.build.unwrap;
let settings: Settings = from_config.unwrap;
vld-utoipa
Bridge between vld and utoipa. Define validation once, get
ToSchema for free — no need to duplicate schema definitions.
Works with both vld::schema! and #[derive(Validate)].
[]
= { = "0.1", = ["openapi"] }
= "0.1"
= "5"
use *;
use impl_to_schema;
// Option A: schema! macro
schema!
impl_to_schema!;
// Option B: derive macro (requires features = ["derive", "openapi"])
impl_to_schema!;
// OpenAPI schema uses camelCase: "firstName", "emailAddress"
Nested schemas are automatically registered in utoipa's components/schemas:
schema!
impl_to_schema!;
schema!
impl_to_schema!;
// Order.address → { "$ref": "#/components/schemas/Address" }
// Address schema is auto-registered — no manual listing needed
vld-aide
Bridge between vld and aide / schemars. Define validation once, get
JsonSchema for free — no need to duplicate with #[derive(JsonSchema)].
Works with both vld::schema! and #[derive(Validate)].
[]
= { = "0.1", = ["openapi"] }
= "0.1"
= { = "0.15", = ["axum"] }
use *;
use impl_json_schema;
schema!
impl_json_schema!;
// Now usable with aide::axum::Json<CreateUser> for OpenAPI 3.1 docs.
vld-schemars
General-purpose bidirectional bridge between vld and schemars.
Unlike vld-aide (which targets aide specifically), vld-schemars works with any schemars-based
library (paperclip, okapi, dropshot, etc.). Provides conversion in both directions, introspection,
comparison, and schema merge utilities.
[]
= { = "0.1", = ["openapi"] }
= "0.1"
use *;
use impl_json_schema;
schema!
impl_json_schema!;
// schemars → vld
let schema = ;
// Introspection
let props = list_properties;
assert!;
vld-rocket
Rocket integration with validation extractors and JSON error catchers.
[]
= "0.1"
= { = "0.5", = ["json"] }
use *;
schema!
vld-poem
Poem integration — extractors VldJson, VldQuery, VldForm.
[]
= "0.1"
= "3"
use handler;
use *;
schema!
async
vld-warp
Warp integration — filters vld_json, vld_query + handle_rejection.
[]
= "0.1"
= "0.3"
use *;
use Filter;
schema!
let route = post
.and
.and
.map
.recover;
vld-sea
SeaORM integration — validate ActiveModel before insert/update.
[]
= "0.1"
= "1"
use Set;
use *;
schema!
let am = ActiveModel ;
// Validate before insert
?;
// Or hook into before_save automatically:
// vld_sea::impl_vld_before_save!(ActiveModel, UserInput);
vld-clap
Clap integration — validate CLI arguments via #[derive(Validate)] directly on the struct.
[]
= "0.1"
= { = "0.1", = ["derive"] }
= { = "4", = ["derive"] }
= { = "1", = ["derive"] }
use Parser;
use Validate;
use *;
vld-salvo
Salvo integration — extractors implement Extractible and work as
#[handler] function parameters, just like Salvo's built-in JsonBody or PathParam.
[]
= "0.1"
= "0.89"
use *;
use *;
schema!
async
vld-tauri
Tauri IPC validation — commands, events, state, channels, plugin config.
Zero dependency on tauri — only vld + serde + serde_json.
[]
= "0.1"
= "2"
use *;
schema!
// Pattern 1 — explicit
// Pattern 2 — auto-validated
vld-fake
Generate fake / test data that satisfies vld validation schemas. Define rules once —
get instant, constraint-aware random data for tests, seed scripts, and demos.
[]
= { = "0.1", = ["openapi"] }
= "0.1"
use *;
use *;
schema!
impl_fake!;
// Typed access — user.name, user.email, user.age
let user = fake;
println!;
// Multiple + reproducible
let users = fake_many;
let same = fake_seeded;
vld-sqlx
SQLx integration — validate before insert/update, typed column wrappers with Type/Encode/Decode.
Supports SQLite, PostgreSQL, MySQL. Generic trait impls work with any backend.
[]
= "0.1"
= { = "0.1", = ["serialize"] }
= { = "0.8", = ["sqlite", "runtime-tokio"] }
use *;
schema!
let user = NewUser ;
?;
// VldText — validated column type, bindable in sqlx queries
let email = new?;
query
.bind
.execute.await?;
vld-surrealdb
SurrealDB integration — validate JSON documents before create/insert/update
and after select. Zero dependency on the surrealdb crate — works with any SDK version.
[]
= "0.1"
= "2" # or "3"
use *;
schema!
let person = Person ;
?;
// db.create("person").content(person).await?;
vld-tonic
tonic gRPC integration — validate protobuf messages and metadata.
[]
= "0.1"
use Serialize;
use ;
impl_validate!;
async
vld-leptos
Leptos integration — define validation rules once, use on server and client (WASM).
Zero dependency on leptos — works with any Leptos version.
[]
= "0.1"
// Shared schemas (server + WASM)
// Server function — validate_args! macro
async
// Client component — reactive check_field
let name_err = new;
vld-dioxus
Dioxus integration — define validation rules once, use on server and client (WASM).
Zero dependency on dioxus — works with any Dioxus version.
[]
= "0.1"
// Shared schemas (server + WASM)
// Server function — validate_args! macro
async
// Client component — reactive check_field
let name_err = use_memo;
vld-ts
Generate TypeScript Zod schemas from JSON Schema output produced by vld.
Useful for sharing validation contracts between Rust backend and TypeScript frontend.
[]
= "0.1"
use generate_zod;
let json_schema = json!;
let ts_code = generate_zod;
// Output: export const UserSchema = z.object({ name: z.string().min(2), email: z.string().email() });
License
MIT