Codegen and test data
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
| Item | Description |
|---|---|
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")) |
prelude | All 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_parsedthen panic,try_fake()/try_fake_parsedreturn the error. $refs resolve against the root's$defs,definitionsorcomponents.schemas.impl_fake!embedsvld::nested!types under$defsautomatically; for a hand-written root schema add them yourself.FakeGen::with_rngtakes arand0.10 RNG. A differentrandmajor in your crate is a differentRngtrait.- Recursion is cut at depth 12, so recursive (
vld::lazy) schemas terminate. - vld's
x-past/x-futuredates keep a two-day margin from "now"; values are still time-dependent. impl_fake!expands to::vld::…paths: depend onvlddirectly, not only through another crate.