Qubit Validator (rs-validator)
qubit-validator supplies reusable typed rules, rule binding, and structured validation reports for Rust applications. Consider a POST /users endpoint: the server must reject a blank username or a malformed email before writing to the user store. This crate is where those checks live as Validator implementations with stable IDs. For applications that use field annotations, those annotations only name rule IDs; the optional qubit-model-metadata integration binds registered rules and walks the object. Keeping the rules in one registry avoids copying the same checks into every handler.
A user registration flow
The frontend sends a username and email. The REST handler parses the request into User and calls the registration service. At startup, the service registers and binds app.non_blank and app.email. For each request, it applies the bound rules to the username and email fields and records their outcomes in a report: invalid input returns field paths and stable codes without a repository write. Only after every intended check completes successfully should a complete report with no failures permit a write; a partial report attached to an execution error is diagnostic evidence only. The HTTP layer can map rejection to a client error and storage or validation execution failure to a server error; HTTP routing and persistence are application code. Apps that declare rules on model fields can use the optional qubit-model-metadata integration described below.
Installation
Rust 1.94 or newer is required. Direct rules and a local registry need only this crate:
[]
= "0.1"
Quick start
Add the dependency above to your application's Cargo.toml, then save this complete program as src/main.rs. It follows a user registration flow: register rules, bind them at application startup, and check each field before writing to the repository. CountingRepository makes the rejection and write branches observable; a service can replace it with its own repository.
use Cell;
use Error;
use fmt;
use Arc;
use ;
;
;
static NON_BLANK_SIGNATURES: & = &;
static NON_BLANK_DESCRIPTOR: ValidatorDescriptor = new;
static NON_BLANK_REGISTRATION: ValidatorRegistration = new;
;
static EMAIL_SIGNATURES: & =
&;
static EMAIL_DESCRIPTOR: ValidatorDescriptor = new;
static EMAIL_REGISTRATION: ValidatorRegistration = new;
;
Run cargo run. The invalid request report contains username: text.blank and email: text.email, and the repository count stays at zero. The valid request is written once. The email rule checks a demonstration ASCII email shape; it does not verify mailbox ownership.
Model annotations
qubit-validator defines, prepares, registers, and executes rules. Object field traversal is provided by qubit-model-metadata. The former #[Model] and ValidationPlan example belongs to this optional advanced path.
For a checkout with the layout below, an application can use these local dependencies. This example is not required to get started with qubit-validator:
<checkout>/rust-common/{rs-validator,rs-model-metadata,rs-reflect,rs-validation-rules}
<checkout>/app
In <checkout>/app/Cargo.toml:
[]
= { = "0.1", = "../rust-common/rs-validator" }
= { = "../rust-common/rs-model-metadata", = ["validation"] }
= { = "../rust-common/rs-model-metadata/derive" }
= { = "../rust-common/rs-reflect" }
In the current checkout, both qubit-model-metadata and qubit-model-derive set publish = false. See the model validation user guide.
What it provides
Validator<T, C>for direct typed rules with domain-specific errors.ValidatorSignature,ValidatorDescriptor, andValidatorRegistryfor selecting and preparing configured rules by stable ID;BoundValidatorchecks the chosen input and dependency shape.ValidationOutcome,Violation, andValidationReportfor separating invalid values from binding or execution failures and collecting caller-visible field results.- Adapters and
ArgumentReaderfor reusable rules with parameters or named dependencies. Optionalinventorydiscovers linked custom registrations.
qubit-validator does not inspect model fields or schedule rules. The Quick Start shows the direct path: bind rules at startup, validate caller-selected fields, and assemble a report before deciding whether to save. Applications that want field annotations and automatic object traversal can use the optional qubit-model-metadata integration described in Model annotations. See the validator user guide for the bind-and-report API and the model validation guide for plan construction, supported access shapes, partial reports, and limits.
Learn more
- Validator user guide · Design · API reference
- Model validation guide · Field declaration guide
- 中文 README · 中文用户手册
Testing
Default cargo fmt --check may report differences from the project format; do
not apply its full-repository diff.
# Run tests with the default feature set
# Run tests with all declared features
# Project CI checks
# Check code coverage
License
Copyright (c) 2025 - 2026. Haixing Hu. All rights reserved.
Licensed under the Apache License, Version 2.0. See LICENSE for the full license text.
Contributing
Contributions are welcome. Please follow the Rust API guidelines, keep public
API documentation and tests current, and run ./.infra/bin/align-ci.sh to format code and
./.infra/bin/ci-check.sh to satisfy CI requirements before submitting a pull request.
Author
Haixing Hu - Qubit Co. Ltd.
Repository: https://github.com/qubit-ltd/rs-validator