Skip to main content

Crate adapters

Crate adapters 

Source
Expand description

High-performance, schema-driven data validation, serialization, deserialization, and structural transformation library for Rust.

This crate provides a unified and extensible API for defining data schemas at runtime or compile-time (via derive macros), parsing and validating JSON natively without external parser dependencies, and transforming data dynamically.

§Unified Schema & Validation Layer

Instead of validating data after parsing it into structured models (which can cause panics or silent errors on invalid types), adapters defines a declarative, dynamic schema tree. Inbound payloads are verified at the dynamic level first, matching strict type names, number ranges, string lengths, custom regexes, and complex formats (e.g., Email or URLs).

§Nested Schema Validation

adapters natively supports recursive validation of complex nested structures. When a structure derives Schema, its schema definition incorporates the schema of any sub-structures that also implement SchemaProvider.

For example, when validating a parent struct like User, any nested objects (e.g., Address) will be fully validated against their own schemas. Any validation failures in the nested child are reported with correct dot-notation paths (e.g., address.city or address.zip_code).

use adapters::prelude::*;
use adapters::Schema;

#[derive(Schema, Debug)]
struct Address {
    #[schema(min_length = 3)]
    city: String,
    country: String,
}

#[derive(Schema, Debug)]
struct User {
    name: String,
    address: Address, // Automatically delegates validation to Address::schema()!
}

§High-Performance Serialization & Deserialization

adapters features highly optimized and fully type-safe serialization and deserialization traits. These traits define how memory structures are converted to and from intermediate Value dynamic trees.

§Safety and Strict Numeric Bounds

Unlike naive decoders that might cause silent overflows, adapters performs type-safe checks during deserialization:

  • If you deserialize a value of 300 into a u8 field, it will return a clean DeserializationError explaining that 300 overflows the bounds of u8.
  • If an unsigned integer type (e.g., u32) receives a negative value (e.g., -10), it is caught and rejected immediately.

§Functional Data Transformation

Domain models often diverge between different contexts (e.g., Database Models vs. API Presentation Models). Using Pipeline and FieldMapper classes, you can map, rename, and transform data trees programmatically in a highly functional manner.

use adapters::prelude::*;

let transform_pipeline = Pipeline::new()
    .step(|val| match val {
        Value::Int(n) => Ok(Value::Int(n * 2)),
        other => Ok(other),
    });

let result = transform_pipeline.run(Value::Int(5)).unwrap();
assert_eq!(result, Value::Int(10));

§Complete Macro Reference

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

Attribute RuleSupported TypesAction Description
min_length = <usize>StringEnforces a minimum string character count.
max_length = <usize>StringEnforces a maximum string character count.
non_emptyStringRestricts string to be non-empty (minimum 1 character).
alphanumericStringEnforces only alphanumeric characters.
emailStringMatches the string value against standard RFC 5322 format.
urlStringMatches the string value against standard URL layout.
regex = "<pattern>"StringValidates string matching using custom Rust regex.
min = <number>All numbersRestricts numbers to be greater than or equal to value.
max = <number>All numbersRestricts numbers to be less than or equal to value.
positiveAll numbersChecks if numbers are strictly positive ($>0$).
negativeAll numbersChecks if numbers are strictly negative ($<0$).
non_zeroAll numbersRestricts numbers to exclude exact $0$ value.
optionalAll typesDeclares the field is non-required and defaults to null.
strictAll typesOpts into strict validation: no implicit type coercions.
default = <expr>All typesPopulates field with expression value when key is absent.

Re-exports§

pub use adapter::Adapter;
pub use adapter::Validate;
pub use deserializer::Deserialize;
pub use error::Error;
pub use error::ValidationError;
pub use error::ValidationErrors;
pub use schema::ArraySchema;
pub use schema::BoolSchema;
pub use schema::EnumSchema;
pub use schema::FloatSchema;
pub use schema::IntegerSchema;
pub use schema::NullSchema;
pub use schema::ObjectSchema;
pub use schema::Schema;
pub use schema::SchemaProvider;
pub use schema::SchemaValidator;
pub use schema::StringSchema;
pub use serializer::Serialize;
pub use transform::Adapt;
pub use transform::FieldMapper;
pub use transform::Pipeline;
pub use value::Value;

Modules§

adapter
The Adapter trait — the central interface for data schema validation, serialization, deserialization, and representation mapping in the library.
deserializer
Deserialization — converting generic Value instances into concrete Rust types.
error
Error types for the adapters library.
json
Native JSON engine — high-performance parse and stringify functionality.
json_utils
Utility module providing native, highly optimized JSON parsing and serialization functions.
prelude
The prelude module re-exports the most commonly used traits and types for ergonomic integration across projects.
schema
Schema module — schema types, the SchemaValidator trait, and the unified Schema enum.
serializer
Serialization — converting Rust structures and primitive types into generic Value instances.
transform
Transformation utilities — Adapt trait, Pipeline, and FieldMapper.
validator
Validator module — reusable, composable validation building blocks.
value
Universal interchange Value type used across every module.

Derive Macros§

Schema
Proc-macro derive entrypoint that configures validation and serialization bindings.