Thanks to visit codestin.com
Credit goes to lib.rs

#json-schema #generator

vld-fake

Generate fake / test data from vld JSON Schemas

1 unstable release

new 0.1.1 Feb 12, 2026

#252 in Testing

MIT license

380KB
8K SLoC

Crates.io docs.rs License Platform GitHub issues GitHub stars

vld-fake

Generate fake / test data that satisfies vld validation schemas.

Define your rules once with vld and get instant, constraint-aware random data — perfect for unit tests, property-based testing, seed scripts, and demos.

Features

Feature Description
fake_value(schema) Random serde_json::Value from a JSON Schema
fake_json(schema) Pretty-printed JSON string
fake_many(schema, n) Generate n values at once
fake_parsed::<T>(schema) Typed + validated instance via T::vld_parse_value
try_fake_parsed::<T>(schema) Same but returns Result
fake_value_seeded(schema, seed) Reproducible output with a fixed seed
FakeGen::with_rng(rng) Bring your own Rng

Supported JSON Schema features

  • Types: string, integer, number, boolean, array, object, null
  • String formats: email, uuid, url/uri, ipv4, ipv6, hostname, date, time, date-time, base64, cuid2, ulid, nanoid, emoji, phone, credit-card, mac-address, hex-color, semver, slug
  • Constraints: minLength/maxLength, minimum/maximum, exclusiveMinimum/exclusiveMaximum, multipleOf, minItems/maxItems, uniqueItems
  • Combinators: enum, const, oneOf, anyOf, allOf, prefixItems (tuples)
  • Objects: properties, required, additionalProperties

Smart field-name heuristics

When generating object properties, field names are used to infer realistic data even without an explicit format:

Field name pattern Generated data
name, full_name, author Realistic full name ("Alice Johnson")
first_name First name from dictionary
last_name, surname Last name from dictionary
username, login, handle Lowercase name + digits ("alice42")
email, mail Realistic email ("[email protected]")
phone, mobile, tel Phone number ("+1 (555) 123-4567")
city, town Real city name
country Real country name
state, province US state name
street, address Street address ("1234 Oak Avenue")
zip, postal_code 5-digit zip code
company, organization Company name
department Department name
job_title, position Job title
url, website, link Realistic URL
domain, hostname Domain name
id, uuid, guid UUID v4
password, secret Strong password (10-18 chars, mixed)
token, api_key Random alphanumeric token
description, bio, summary Lorem-style sentence
product_name, item "Adjective Noun" product name
sku, product_code SKU code ("ABC-12345")
category, genre Category from dictionary
tag, label Tag from dictionary
color, colour Color name
hex_color Hex color ("#a3f2c1")
currency ISO currency code
locale, lang Locale code ("en-US")
timezone, tz IANA timezone
mime_type, content_type MIME type
file_name File name with extension
version, semver Semver string ("1.4.12")
credit_card Luhn-valid card number
isbn Valid ISBN-13
latitude, longitude Geo coordinates
user_agent Realistic browser UA string
mac_address MAC address

Dictionaries

The crate ships with built-in dictionaries (~2000 entries total):

  • 200 first names, 130 last names
  • 95 cities, 50 countries, 50 US states
  • 48 street names, 20 street suffixes
  • 40 companies, 22 departments, 39 job titles
  • 35 adjectives, 38 product nouns, 26 categories, 27 tags
  • 15 email domains, 24 TLDs
  • 20 MIME types, 44 file extensions
  • 39 colors, 27 currencies, 35 locales, 32 timezones
  • 60 emojis, 80 words, 100 lorem words

Installation

[dependencies]
vld = { version = "0.1", features = ["openapi"] }
vld-fake = "0.1"

Quick Start

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

vld::schema! {
    #[derive(Debug, Clone, serde::Serialize)]
    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),
    }
}

// One line — enables User::fake(), User::fake_many(), User::fake_seeded()
vld_fake::impl_fake!(User);

fn main() {
    // Typed access — user.name, user.email, user.age
    let user = User::fake();
    println!("{} <{}> age={}", user.name, user.email, user.age);

    // Multiple at once
    let users = User::fake_many(5);
    for u in &users {
        println!("  {} <{}>", u.name, u.email);
    }

    // Reproducible — same seed → same data
    let u1 = User::fake_seeded(42);
    let u2 = User::fake_seeded(42);
    assert_eq!(u1.name, u2.name);

    // Fallible variant
    let result = User::try_fake();
    assert!(result.is_ok());
}

Low-level (untyped) API

If you need raw serde_json::Value or work with arbitrary JSON Schemas:

let schema = User::json_schema();
let value = fake_value(&schema);        // -> serde_json::Value
let json  = fake_json(&schema);         // -> String
let many  = fake_many(&schema, 10);     // -> Vec<Value>
let seeded = fake_value_seeded(&schema, 42);

Nested Schemas

vld::schema! {
    #[derive(Debug, Clone, serde::Serialize)]
    pub struct Address {
        pub city: String => vld::string().min(1),
        pub zip:  String => vld::string().min(5).max(10),
    }
}

vld::schema! {
    #[derive(Debug, Clone, serde::Serialize)]
    pub struct UserWithAddress {
        pub name:    String  => vld::string().min(2),
        pub address: Address => vld::nested(Address::parse_value),
    }
}

let schema = UserWithAddress::json_schema();
let value = fake_value(&schema);
// { "name": "kRtBwZ", "address": { "city": "aBcDe", "zip": "12345" } }

Raw JSON Schema

You don't need vld::schema! — any valid 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 config = vld_fake::fake_value(&schema);

Custom RNG

use rand::SeedableRng;
use vld_fake::FakeGen;

let rng = rand::rngs::StdRng::seed_from_u64(12345);
let mut gen = FakeGen::with_rng(rng);
let value = gen.value(&schema);

Use Cases

  • Unit tests — generate valid fixtures without manual JSON
  • Property-based testing — combine with proptest strategies
  • Seed / migration scripts — fill databases with realistic data
  • API mocking — respond with schema-conforming payloads
  • Documentation — auto-generate example request/response bodies

Running the Example

cargo run -p vld-fake --example fake_basic

License

MIT

Dependencies

~0.8–1.7MB
~36K SLoC