High-performance JSON Logic evaluation library with schema validation and multi-platform bindings
json-eval-rs is a blazing-fast JSON Logic evaluator written in Rust, featuring a custom-built compiler, intelligent caching, and comprehensive schema validation. It provides seamless integration across multiple platforms through native bindings.
- π High Performance: Custom JSON Logic compiler with pre-compilation and zero-copy caching
- π Topological Sorting: Dependency-aware processing to ensure correct evaluation order
- π Schema Validation: Built-in validation with detailed error reporting
- π Multi-Platform: Native bindings for Rust, C#/.NET, Web (WASM), and React Native
- πΎ Smart Caching: Content-based caching with Arc-based zero-copy storage
- π Dependency Tracking: Automatic field dependency detection for selective re-evaluation
- π SIMD Optimized: Uses
simd-jsonfor ultra-fast JSON parsing - β‘ Selective Evaluation: Re-evaluate only specific fields for improved performance
- π Timezone Support: Configurable timezone offset for date/time operations
- Dynamic Form Validation: Real-time validation with complex business rules
- Configuration Management: Evaluate dynamic configurations with dependencies
- Business Rule Engines: Execute complex business logic with high performance
- Data Transformation: Transform and validate large datasets efficiently
- UI Layout Resolution: Resolve conditional layouts with
$refreferences - Interactive Forms: Selective re-evaluation for efficient field updates
- Multi-Timezone Applications: Handle date/time operations across different timezones
π Comprehensive Operator Documentation - Complete guide to all 80+ available operators:
- Quick Reference - Alphabetical operator list
- Core Operators - Variables and literals
- Logical Operators - Boolean logic (
and,or,if, etc.) - Comparison Operators - Value comparisons (
==,<,>, etc.) - Arithmetic Operators - Math operations (
+,-,*,/, etc.) - String Operators - Text manipulation (
cat,substr,search, etc.) - Math Functions - Advanced math (
round,abs,max, etc.) - Date Functions - Date/time operations (
today,dateformat, etc.) - Array Operators - Array transformations (
map,filter,reduce, etc.) - Table Operators - Data lookups (
VALUEAT,INDEXAT, etc.) - Utility Operators - Helper functions (
missing,RANGEOPTIONS, etc.)
[dependencies] json-eval-rs = "0.0.75"dotnet add package JsonEvalRsyarn add @json-eval-rs/webcore # Then add either specific backend: yarn add @json-eval-rs/bundler # (For Vite/Webpack) # OR yarn add @json-eval-rs/vanilla # (For Vanilla JS)yarn install @json-eval-rs/react-nativeSelective evaluation allows you to re-evaluate only specific fields in your schema, significantly improving performance for partial updates.
Benefits:
- β‘ Faster updates when only a few fields change
- πΎ Reduced cache invalidation
- π― Perfect for interactive forms and real-time validation
- π Scales well with large schemas
Rust Example:
use json_eval_rs::JSONEval; let mut eval = JSONEval::new(&schema, None, Some(&data))?; // Full evaluation eval.evaluate(&data, None, None)?; // Later, selectively re-evaluate only specific fields let paths = vec![ "user.email".to_string(), "billing.total".to_string() ]; eval.evaluate(&updated_data, None, Some(&paths))?;C# Example:
using JsonEvalRs; var eval = new JSONEval(schema); eval.Evaluate(data); // Selective re-evaluation var paths = new[] { "user.email", "billing.total" }; eval.Evaluate(updatedData, paths: paths);Web/TypeScript Example:
import { JSONEval } from "@json-eval-rs/web"; const eval = new JSONEval({ schema: JSON.stringify(schema) }); await eval.evaluateJS({ data: JSON.stringify(data) }); // Selective re-evaluation await eval.evaluateJS({ data: JSON.stringify(updatedData), paths: ["user.email", "billing.total"] });How it works:
- Pass field paths in dotted notation (e.g.,
"field.nested.property") - Only specified fields and their dependencies are recalculated
- Other fields retain their previously evaluated values
- Cache is selectively purged only for affected fields
Configure timezone offset for all date/time operations without external dependencies.
Benefits:
- π Handle dates in any timezone
- π Runtime timezone switching
- π No external datetime library required
- π Consistent date handling across platforms
Rust Example:
use json_eval_rs::JSONEval; let mut eval = JSONEval::new(&schema, None, None)?; // Set to UTC+7 (Bangkok, Jakarta) - 420 minutes offset eval.set_timezone_offset(Some(420)); eval.evaluate(&data, None, None)?; // Reset to UTC eval.set_timezone_offset(None);C# Example:
using JsonEvalRs; var eval = new JSONEval(schema); // Set timezone to UTC+7 (420 minutes) eval.SetTimezoneOffset(420); eval.Evaluate(data); // Reset to UTC eval.SetTimezoneOffset(null);Web/TypeScript Example:
import { JSONEval } from "@json-eval-rs/web"; const eval = new JSONEval({ schema: JSON.stringify(schema) }); // Set timezone to UTC+7 eval.setTimezoneOffset(420); await eval.evaluateJS({ data: JSON.stringify(data) }); // Reset to UTC eval.setTimezoneOffset(null);Common Timezone Offsets:
- UTC:
0ornull - UTC+7 (Bangkok, Jakarta):
420 - UTC+9 (Tokyo, Seoul):
540 - UTC-5 (EST):
-300 - UTC-8 (PST):
-480 - UTC+1 (CET):
60
Affected Operations:
TODAY- Current date at midnight in the specified timezoneNOW- Current timestamp in the specified timezoneDATEFORMAT- Formats dates using the timezone offset- All date arithmetic operations
use json_eval_rs::JSONEval; fn main() -> Result<(), Box<dyn std::error::Error>> { let schema = r#"{ "type": "object", "properties": { "name": { "rules": { "required": { "value": true, "message": "Name is required" } } } } }"#; let mut eval = JSONEval::new(schema, None, None)?; let data = r#"{"name": "John Doe"}"#; eval.evaluate(data, None)?; let result = eval.get_evaluated_schema(false); // Validate the data let validation = eval.validate(data, None, None)?; if !validation.has_error { println!("β
Data is valid!"); } else { println!("β Validation errors: {:?}", validation.errors); } Ok(()) }using JsonEvalRs; var schema = @"{ ""type"": ""object"", ""properties"": { ""age"": { ""rules"": { ""minValue"": { ""value"": 18, ""message"": ""Must be 18 or older"" } } } } }"; using (var eval = new JSONEval(schema)) { var data = @"{""age"": 25}"; var result = eval.Evaluate(data); var validation = eval.Validate(data); if (!validation.HasError) { Console.WriteLine("β
Data is valid!"); } }import { JSONEval } from "@json-eval-rs/web"; const schema = { type: "object", properties: { email: { rules: { required: { value: true, message: "Email is required" }, pattern: { value: "^[^@]+@[^@]+\\.[^@]+$", message: "Invalid email format", }, }, }, }, }; const eval = new JSONEval({ schema: JSON.stringify(schema) }); const data = { email: "user@example.com" }; const result = await eval.evaluateJS({ data: JSON.stringify(data) }); const validation = await eval.validate({ data: JSON.stringify(data) }); if (!validation.has_error) { console.log("β
Data is valid!"); } eval.free(); // Clean up memoryimport { useJSONEval } from "@json-eval-rs/react-native"; function ValidationForm() { const eval = useJSONEval({ schema }); const [formData, setFormData] = useState({ name: "", age: "" }); const [errors, setErrors] = useState({}); const validateForm = async () => { if (!eval) return; const validation = await eval.validate({ data: JSON.stringify(formData), }); setErrors(validation.errors || {}); }; return ( <View> <TextInput value={formData.name} onChangeText={(name) => setFormData({ ...formData, name })} onBlur={validateForm} /> {errors.name && ( <Text style={{ color: "red" }}>{errors.name.message}</Text> )} </View> ); }- JSONEval: Main orchestrator handling the complete evaluation pipeline
- RLogic Engine: Custom JSON Logic compiler with pre-compilation and caching
- EvalData: Proxy-like data wrapper ensuring thread-safe mutations
- EvalCache: Content-based caching system using Arc for zero-copy storage
- Table Evaluator: Specialized processing for table/array data
- Schema Parser: Extracts evaluations and builds dependency graphs
- Topological Sort: Groups evaluations into parallel-executable batches
- Schema Parsing β Extract evaluations and build dependency graph
- Logic Compilation β Pre-compile JSON Logic expressions for performance
- Topological Sorting β Group evaluations into dependency-ordered batches
- Batch Evaluation β Execute batches sequentially with caching
- Result Aggregation β Clean results and resolve layout references
| Operation | json-eval-rs | Native JS | Improvement |
|---|---|---|---|
| Parse Complex Schema | 3ms | 15ms | 5x faster |
| Evaluate 1000 Rules | 8ms | 45ms | 5.6x faster |
| Validate Large Form | 2ms | 12ms | 6x faster |
| Cache Hit Lookup | 0.1ms | 2ms | 20x faster |
Benchmarks run on Intel i7 with complex real-world schemas
- Pre-compilation: JSON Logic expressions compiled once, evaluated many times
- Zero-Copy Caching: Results cached using
Arc<Value>to avoid deep cloning - SIMD JSON: Uses
simd-jsonfor ultra-fast JSON parsing - Smart Dependencies: Only re-evaluates fields when their dependencies change
- Selective Evaluation: Re-evaluate only specific fields instead of entire schema
- Intelligent Cache Purging: Selective cache invalidation for changed fields only
The library includes comprehensive examples demonstrating various use cases:
Simple evaluation with automatic scenario discovery:
# Run all scenarios cargo run --example basic # Run specific scenario cargo run --example basic zcc # Enable comparison with expected results cargo run --example basic --compareAdvanced benchmarking with ParsedSchema caching and concurrent testing:
# Run with 100 iterations cargo run --example benchmark -- -i 100 zcc # Use ParsedSchema for efficient caching cargo run --release --example benchmark -- --parsed -i 100 zcc # Test concurrent evaluations (4 threads, 10 iterations each) cargo run --example benchmark -- --parsed --concurrent 4 -i 10 # Full benchmarking suite with comparison cargo run --release --example benchmark -- --parsed -i 100 --compareFor more details, see examples/README.md.
A powerful CLI tool for direct schema evaluation with parsed schema inspection:
# Simple evaluation cargo run --bin json-eval-cli -- schema.json -d data.json # With comparison and ParsedSchema cargo run --bin json-eval-cli -- schema.json -d data.json \ -c expected.json --parsed -i 100 # Inspect parsed schema structure cargo run --bin json-eval-cli -- schema.json -d data.json \ --parsed --no-output \ --print-sorted-evaluations \ --print-dependencies # All parsed schema information cargo run --bin json-eval-cli -- schema.json -d data.json \ --parsed --print-all # Full options with MessagePack support cargo run --bin json-eval-cli -- schema.bform \ --data data.bform \ --compare expected.json \ --compare-path "$.$params.others" \ --parsed \ --iterations 100 \ --output result.jsonParsed Schema Inspection Flags:
--print-sorted-evaluations- Show evaluation batches organized sequentially--print-dependencies- Show dependency graph between evaluations--print-tables- Show table definitions--print-evaluations- Show all compiled logic expressions--print-all- Show all parsed schema information
Run cargo run --bin json-eval-cli -- --help for full documentation.
π JSON Evaluation Benchmark ============================== Scenario: zcc Schema: samples/zcc.json Data: samples/zcc-data.json Loading files... Running evaluation... Schema parsing & compilation: 3.2ms Total evaluation time: 12.4ms Average per iteration: 124ΞΌs Cache: 1,247 entries, 8,932 hits, 89 misses (99.0% hit rate) β±οΈ Execution time: 15.6ms β
Results saved: - samples/zcc-evaluated-schema.json - samples/zcc-parsed-schema.json - samples/zcc-evaluated-value.json | Platform | Technology | Performance | Bundle Size |
|---|---|---|---|
| Rust | Native | Native | N/A |
| C# / .NET | P/Invoke FFI | Native | ~2MB |
| Web | WebAssembly | Near-native | ~450KB gzipped |
| React Native | Native Modules (JSI) | Native | Native code |
- Linux: x86_64, ARM64
- Windows: x86_64
- macOS: x86_64, ARM64 (Apple Silicon)
- Web: All modern browsers, Node.js 14+
- Mobile: iOS 11+, Android API 21+ (supports Android 15+ 16KB page sizes)
- Rust: Latest stable (for core development)
- .NET SDK 6.0+: For C# bindings
- Node.js 18+: For Web/React Native bindings
- wasm-pack: For WebAssembly builds
# Clone the repository git clone https://github.com/byrizki/jsoneval-rs.git cd json-eval-rs # Build the core library cargo build --release # Run tests cargo test # Build all language bindings ./build-bindings.sh all # Run CLI tool with examples cargo run --bin json-eval-cli- API Documentation - Complete Rust API reference
- C# Documentation - .NET integration guide
- Web Documentation - JavaScript/TypeScript usage
- React Native Documentation - Mobile development guide
- Architecture Guide - Deep dive into internals
We welcome contributions! Please see our Contributing Guidelines for details.
- Fork and clone the repository
- Install dependencies:
cargo build - Run tests:
cargo test - Make your changes
- Add tests for new functionality
- Run
cargo fmtandcargo clippy - Submit a pull request
# Build specific binding ./build-bindings.sh csharp # C# only ./build-bindings.sh web # Web only ./build-bindings.sh react-native # React Native only # Package for publishing ./build-bindings.sh packagejson-eval-rs uses an extended JSON Schema format with evaluation rules:
{ "type": "object", "properties": { "fieldName": { "type": "string", "rules": { "required": { "value": true, "message": "This field is required" }, "minLength": { "value": 3, "message": "Must be at least 3 characters" }, "pattern": { "value": "^[A-Za-z]+$", "message": "Only letters allowed" } }, "condition": { "hidden": { "==": [{ "var": "other.field" }, "hide"] }, "disabled": { "!=": [{ "var": "user.role" }, "admin"] } } } }, "$layout": { "elements": [ { "type": "input", "$ref": "#/properties/fieldName" } ] } }required: Field must have a valueminLength/maxLength: String/array length validationminValue/maxValue: Numeric range validationpattern: Regular expression validation- Custom rules via JSON Logic expressions
The library provides detailed error information:
match eval.validate(data, None, None) { Ok(validation) => { if validation.has_error { for (field, error) in validation.errors { println!("Field '{}': {} ({})", field, error.message, error.rule_type); } } }, Err(e) => eprintln!("Validation error: {}", e), }This project is licensed under the MIT License - see the LICENSE file for details.
For commercial support, consulting, or custom development, please contact us at support@example.com.
- Built with Rust for maximum performance and safety
- Uses simd-json for high-speed JSON parsing
- Inspired by the JSON Logic specification
- WebAssembly bindings powered by wasm-bindgen
β Star this repository if you find it useful!