Codegen and test data
Generate random test data that passes your vld schemas, typed or as raw JSON, with optional seeds.

vld-fake walks a JSON Schema (from a vld type or written by hand) and produces values that satisfy it: formats, patterns, length and numeric bounds, multipleOf, array and object counts, unions, tuples and $refs. Field names drive realistic values (email, city, first_name, sku, …) when no format is set. Use it for fixtures, seed scripts, mock responses and property tests.

Install

Cargo.toml
[dependencies]
vld = { version = "0.5", features = ["openapi"] }
vld-fake = "0.5"

Usually a [dev-dependencies] entry. No optional features. MSRV: 1.85 (see MSRV).

Example

use vld::prelude::*;
use vld_fake::FakeData;

vld::schema! {
    #[derive(Debug)]
    pub struct User {
        pub name:  String => vld::string().min(2).max(50),
        pub email: String => vld::string().email(),
        pub age:   i64    => vld::number().int().min(18).max(99),
    }
}

vld_fake::impl_fake!(User);

let user = User::fake();                 // validated through User::parse_value
assert!(user.email.contains('@'));

let users = User::fake_many(5);
assert_eq!(User::fake_seeded(42).name, User::fake_seeded(42).name);

// Untyped: any JSON Schema works
let schema = serde_json::json!({
    "type": "object",
    "required": ["host", "port"],
    "properties": {
        "host": { "type": "string", "format": "ipv4" },
        "port": { "type": "integer", "minimum": 1, "maximum": 65535 }
    }
});
let value = vld_fake::fake_value(&schema);
assert!(value["port"].as_i64().unwrap() >= 1);

API

ItemDescription
impl_fake!(T)FakeData for a type with json_schema() and VldParse (schema!, derive)
FakeData::{fake, fake_many, fake_seeded, try_fake}Typed, validated instances
fake_value(&schema) / fake_json(&schema) / fake_many(&schema, n)Raw serde_json::Value, pretty JSON string, n values
fake_value_seeded(&schema, seed)Reproducible value
fake_parsed::<T>(&schema) / try_fake_parsed::<T>(&schema)Generate and parse through T::vld_parse_value (panics / Result)
FakeGen::new() / FakeGen::with_rng(rng)Stateful generator; value(&schema), value_with_hint(&schema, Some("email"))
preludeAll of the above

Gotchas

  • Generated strings are checked with vld's own format checks before they are returned. Contradictory schemas (uuid().max(10), hex().uuid()) end in a best-effort value that fails validation: fake() / fake_parsed then panic, try_fake() / try_fake_parsed return the error.
  • $refs resolve against the root's $defs, definitions or components.schemas. impl_fake! embeds vld::nested! types under $defs automatically; for a hand-written root schema add them yourself.
  • FakeGen::with_rng takes a rand 0.10 RNG. A different rand major in your crate is a different Rng trait.
  • Recursion is cut at depth 12, so recursive (vld::lazy) schemas terminate.
  • vld's x-past / x-future dates keep a two-day margin from "now"; values are still time-dependent.
  • impl_fake! expands to ::vld::… paths: depend on vld directly, not only through another crate.