The validation module provides a modern, declarative, and type-safe way to validate data in C++.
It is designed for:
- backend APIs
- forms and user input
- configuration files
- domain models
- both beginners and advanced C++ developers
This module favors clarity, composability, and zero hidden magic.
Validation in Vix is built around a few strong principles:
- Declarative: describe what is valid, not how to check it
- Type-safe: errors are caught at compile time when possible
- Composable: rules, schemas, and forms can be reused and combined
- Explicit: no exceptions, no implicit conversions
- Beginner-friendly but expert-ready
You can start with simple string validation and grow toward full form binding and cleaned output without changing your mental model.
The module is structured around five main building blocks:
| Concept | Purpose |
|---|---|
Validator<T> |
Fluent validation of a single value |
Schema<T> |
Declarative validation rules for a struct |
Form<T> |
Bind raw input + validate + produce output |
BaseModel<T> |
CRTP helper for schema-driven models |
ValidationResult / ValidationErrors |
Structured error reporting |
Use validate(field, value) for quick checks.
#include <vix/validation/Validate.hpp>
auto r = vix::validation::validate("email", email)
.required()
.email()
.length_max(120)
.result();
if (!r.ok())
{
// handle r.errors
}Examples:
examples/simple_string.cppexamples/validate_string.cppexamples/validate_enum.cpp
struct User
{
std::string email;
std::string password;
static vix::validation::Schema<User> schema()
{
return vix::validation::schema<User>()
.field("email", &User::email,
vix::validation::field<std::string>()
.required()
.email()
.length_max(120))
.field("password", &User::password,
vix::validation::field<std::string>()
.required()
.length_min(8)
.length_max(64));
}
};Examples:
examples/schema_fieldspec_basic.cppexamples/schema.cpp
.field("email", &User::email,
[](std::string_view f, const std::string &v)
{
return vix::validation::validate(f, v)
.required()
.email();
})Examples:
examples/schema_lambda_builder.cpp
.check([](const User &u, ValidationErrors &errors)
{
if (u.password != u.confirm)
{
errors.add("confirm",
ValidationErrorCode::Custom,
"passwords do not match");
}
});Examples:
examples/schema_cross_field_check.cpp
Examples:
examples/parsed.cppexamples/form_parsed_age.cppexamples/validate_parsed_int.cpp
Examples:
examples/form_kv_basic.cppexamples/form_cleaned_output.cppexamples/form_bind2_generic_error.cpp
Examples:
examples/basemodel_basic.cppexamples/basemodel_static_validate.cppexamples/basemodel_cross_field_check.cpp
Errors are structured, not strings.
ValidationError fields:
- field
- code
- message
Codes:
- Required
- Min, Max
- LengthMin, LengthMax
- Between
- Format
- InSet
- Custom
Unit tests live in tests/.
Run:
ctestMIT Part of the Vix.cpp project.