adapters 0.0.0

A high-performance, native Rust schema validation, serialization, deserialization, and data transformation library.
Documentation

Documentation | API Reference | Quick Start | Contributing

A production-grade, high-performance schema and data transformations library for Rust, designed with a clean, intuitive, and developer-friendly API.

[!NOTE] This Project aims to be production ready, while it is relatively new project you can find some interesting features which may simplify your Rust project structured validations and data transformations.

⭐️ If you love adapters, make sure to give it a star! ⭐️



Feature Description Documentation
Declarative Derive Macro User-friendly data modeling interface via #[derive(Schema)] Docs
Comprehensive Field Rules email, url, min/max bounds, regex, non_empty, alphanumeric, positive, negative, and non_zero Docs
Coercion & Strict Mode Optional strict type enforcement to prevent implicit casting / type parsing Docs
Dynamic Schema Builders Build complex nested structural validations dynamically at runtime Docs
Robust Parsing Engine Native structured JSON parsing with precise escape seq bounds Docs
Functional Pipelines Chain value adjustments, defaults, transformations, and filters cleanly Docs
Nested Validation Error Paths Accumulates nested object failures using accurate dot-notation paths Docs

Prerequisites

Before installing Adapters, ensure you have the following:

Requirement Version Notes
Rust Stable 1.85+ 2024 Edition supported natively
Operating System Windows, Linux, macOS Cross-platform

Supported Platforms

Adapters supports a wide range of platforms and architectures:

Platform Architectures Status
Windows x86_64, aarch64, x86 Full support
Linux x86_64, aarch64, riscv64 Full support
macOS x86_64, aarch64 (Apple Silicon) Full support

Installation

Method 1: Cargo Add (Recommended)

Add Adapters to your cargo project dynamically:

cargo add adapters

Method 2: Manual Cargo.toml Configuration

Add this directly to your Cargo.toml dependencies block:

[dependencies]

adapters = "0.0.0"


Quick Start

use adapters::prelude::*;

#[derive(Schema, Debug)]
struct UserRegistration {
    #[schema(min_length = 3, max_length = 20, alphanumeric)]
    username: String,

    #[schema(email)]
    email: String,

    #[schema(positive)]
    age: u8,
}

fn main() -> Result<(), Error> {
    let raw_payload = r#"{
        "username": "Fiaz2026",
        "email": "contact@example.com",
        "age": 28
    }"#;

    // Direct structural deserialization & validation
    let user = UserRegistration::from_json(raw_payload)?;
    println!("Successfully validated user: {:?}", user);

    Ok(())
}

Usage Examples

Basic Declarative Validation

use adapters::prelude::*;

#[derive(Schema)]
struct SimpleUser {
    name: String,
    #[schema(optional, default = "Guest")]
    role: String,
}

Advanced Macro Validations

use adapters::prelude::*;

#[derive(Schema)]
struct SecureAsset {
    #[schema(non_empty, alphanumeric)]
    serial_code: String,

    #[schema(positive)]
    quantity: i32,

    #[schema(negative)]
    balance_deficit: f64,

    #[schema(non_zero)]
    tracking_id: i64,
}

Programmatic Builder Validation

use adapters::prelude::*;
use adapters::schema::{ObjectSchema, StringSchema, IntegerSchema};
use adapters::SchemaValidator;

let schema = ObjectSchema::new()
    .field("username", StringSchema::new().required().non_empty().alphanumeric())
    .field("age", IntegerSchema::new().required().min(18).positive());

Nested Model Validation

use adapters::prelude::*;

#[derive(Schema)]
struct Address {
    city: String,
    country: String,
}

#[derive(Schema)]
struct Profile {
    name: String,
    address: Address, // Child schema validated recursively!
}

Field Transformation Pipelines & Sanitization

Chaining data mapping and sanitization rules is highly expressive using functional pipelines. This is exceptionally useful when consuming legacy third-party Webhook payloads:

use adapters::prelude::*;
use adapters::transform::{Pipeline, FieldMapper};

// Create a field mapper to rename legacy API keys
let legacy_mapper = FieldMapper::new()
    .rename("txt_title", "title")
    .rename("usr_id", "user_id");

// Build a transformation pipeline
let pipeline = Pipeline::new()
    .push(legacy_mapper)
    .push(|mut value: Value| {
        // Custom sanitization: Force uppercase on the "title" key if present
        if let Some(obj) = value.as_object_mut() {
            if let Some(Value::String(s)) = obj.get_mut("title") {
                *s = s.to_uppercase();
            }
        }
        Ok(value)
    });

// Process a raw legacy payload
let legacy_payload = Value::Object(
    [
        ("txt_title".to_string(), Value::String("Adapters Guide".into())),
        ("usr_id".to_string(), Value::Int(99)),
    ]
    .into_iter()
    .collect()
);

let clean_value = pipeline.run(legacy_payload).unwrap();
println!("Transformed payload: {:?}", clean_value);
// Output will have "title" in uppercase, and "usr_id" renamed to "user_id"!

Alias Key Remapping

If you don't need runtime pipelines and only require direct structural key mapping from your JSON API payloads, use the #[schema(alias = "...")] helper:

use adapters::prelude::*;

#[derive(Schema, Debug)]
struct ApiConfig {
    /// Remaps "serverPort" in JSON directly to "port" in Rust
    #[schema(alias = "serverPort")]
    port: u16,

    /// Remaps "db_host_name" in JSON directly to "host" in Rust
    #[schema(alias = "db_host_name")]
    host: String,
}

Declarative Macro Reference Table

Configure your struct fields using the #[schema(...)] helper:

Attribute Rule Supported Types Action Description
min_length = <usize> String Enforces a minimum string character count.
max_length = <usize> String Enforces a maximum string character count.
non_empty String Restricts string to be non-empty (minimum 1 character).
alphanumeric String Enforces only alphanumeric characters.
email String Matches the string value against standard RFC 5322 format.
url String Matches the string value against standard URL layout.
regex = "<pattern>" String Validates string matching using custom Rust regex.
min = <number> All numbers Restricts numbers to be greater than or equal to value.
max = <number> All numbers Restricts numbers to be less than or equal to value.
positive All numbers Checks if numbers are strictly positive ($>0$).
negative All numbers Checks if numbers are strictly negative ($<0$).
non_zero All numbers Restricts numbers to exclude exact $0$ value.
optional All types Declares the field is non-required and defaults to null.
strict All types Opts into strict validation: no implicit type coercions.
default = <expr> All types Populates field with expression value when key is absent.

Performance & Benchmarks

Adapters is engineered for extreme data validation and parsing throughput. It implements high-performance zero-allocation parsing routines, compact error trees, and static struct validation maps.

To run benchmarks locally:

cargo bench


Building & Testing

# Check compiler requirements and clippy lints

cargo clippy --workspace --all-targets -- -D warnings


# Run all unit, integration, and doctests

cargo test --workspace --all-targets


Documentation

Online Documentation

Full structured guide and dynamic api walkthroughs are available natively at: https://muhammad-fiaz.github.io/adapters

Generating Local Documentation

To generate and view crate-level API documentation locally:

cargo doc --no-deps --open


Contributing

Contributions are welcome! Please feel free to submit a Pull Request. See CONTRIBUTING.md for contribution guidelines.


License

MIT License - see LICENSE for details.


Links