Skip to main content

A high-performance schema validation library for Python, powered by Rust.

Project description

Rod

The Write-Once, Validate-Anywhere Schema Library.

Crates.io NPM PyPI License


Rod is a high-performance schema validation engine powered by Rust. It compiles to native binaries, WebAssembly (Node.js/Browser), and Python extensions, allowing you to enforce the exact same validation logic across your entire stack.

Stop rewriting regexes in three different languages. Define it once in Rod, run it everywhere.

🚀 Key Features

  • Unified Logic: A uuid() check in the browser uses the exact same byte-level logic as your Rust backend. No more "Schema Drift."
  • Zero-Copy Architecture: Rod validates data directly in the host language's memory (V8 Heap, Python Objects, or Rust Structs) without expensive intermediate serialization.
  • Fluent API: A chainable builder pattern (rod.string().min(5)) familiar to Zod/Pydantic users.
  • Batch Optimization: Specialized bitmask APIs for validating massive datasets (100k+ items) with minimal FFI overhead.

📦 Installation

Rust

cargo add rod-rs

JavaScript / TypeScript

npm install rod-js

Python

pip install rod

⚡ Quick Start

1. Rust

Uses the rod_obj! macro for cleaner syntax.

use rod_rs::{rod_obj, string, number, RodValidator};
use serde_json::json;

fn main() {
    // Define schema using the macro
    let user_schema = rod_obj! {
        name: string().min(3),
        email: string().email(),
        age: number().int().min(18.0)
    };

    // Data (e.g., from an API request)
    let data = json!({ 
        "name": "Rod", 
        "email": "hi@rod.rs", 
        "age": 25 
    });

    // Zero-copy wrap & validate
    let input = rod_rs::io::json::wrap(&data);
    
    match user_schema.validate(&input) {
        Ok(_) => println!("✅ Valid!"),
        Err(e) => println!("❌ Error: {:?}", e.issues),
    }
}

2. TypeScript

Requires a one-time WASM initialization.

import { rod } from 'rod-js';

await rod.init(); // Initialize WASM

const User = rod.object({
  name: rod.string().min(3),
  email: rod.string().email(),
  tags: rod.array(rod.string()).min(1)
}).strict();

const data = { 
  name: "Rod", 
  email: "hi@rod.rs", 
  tags: ["wasm", "rust"] 
};

// 'lazy' mode reads fields on-demand without full serialization
console.log(User.parse(data, { mode: 'lazy' }));

3. Python

Native extension via PyO3.

import rod

User = rod.object({
    "name": rod.string().min(3),
    "email": rod.string().email(),
    "tags": rod.array(rod.string()).min(1)
}).strict()

data = {
    "name": "Rod", 
    "email": "hi@rod.rs", 
    "tags": ["ffi", "rust"]
}

try:
    print(User.parse(data))
except ValueError as e:
    print(f"Validation failed: {e}")

📊 Performance & Architecture

Rod prioritizes correctness and portability.

The "Bridge Tax"

Rod runs inside a Rust core. When used from JS or Python, there is an overhead to cross the language boundary (Foreign Function Interface).

  • Simple Objects: For tiny objects (e.g., { a: 1 }), native libraries like Zod (JS) or Pydantic (Python) are faster because they don't pay the FFI tax.
  • Complex Logic: For heavy validation (UUIDs, huge arrays, complex regex), Rod often outperforms native JS/Python logic.
  • Native Rust: Rod is blazingly fast (~200ns per object), comparable to raw handwritten Rust checks.

Recommendation

  • Use Rod when you need strict consistency between Backend/Frontend, or when processing batch data.
  • Use Zod/Pydantic if you are writing a single-language app and don't need shared logic.

🛠 Development

This is a monorepo managed by just.

Command Description
just build-all Build Rust core, WASM bindings, and Python extension
just test-all Run integration tests across all three languages
just bench-all Run comparative benchmarks against Zod and Pydantic

📄 License

MIT © Yash Makan

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rod_py-0.1.1.tar.gz (34.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rod_py-0.1.1-cp312-cp312-macosx_11_0_arm64.whl (921.9 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

Details for the file rod_py-0.1.1.tar.gz.

File metadata

  • Download URL: rod_py-0.1.1.tar.gz
  • Upload date:
  • Size: 34.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.11.5

File hashes

Hashes for rod_py-0.1.1.tar.gz
Algorithm Hash digest
SHA256 a10b6d59932b6e76f3ec533a5c10d35f50cb28663e513fe78292886cdce6ecd9
MD5 891f0b77d3277119493698685aa09905
BLAKE2b-256 fab3395213550a391264e9fae77536fcb45b4e52422d271d20a2926c4c6f0792

See more details on using hashes here.

File details

Details for the file rod_py-0.1.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rod_py-0.1.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 29a2b087dd677ceb0a083e1563d8d591eeb6784d0cc9b3e128a927e5771672f6
MD5 29c750d4ac98b4a170c1d1ea83466be2
BLAKE2b-256 2991585e42f55cc1b97bed42c9b5f262b5756d4f10381bd2d86eda92998fed1a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page